CF17 合集
前言:
- 本人不会 LaTeX……请见谅
- 码风奇特,不喜勿喷哈
- 题面翻译取自 luogu,本蒟蒻也会安置原题链接
- 保证文章中不出现“显然”或者“注意到”,可能会出现“易证”
- AC 代码会放置在每一个题目的最底端,为防止 ban 码的情况出现,不设置跳转链接
- 有写错的地方欢迎各位神犇指正
- 本套题共 \(5\) 道,预计阅读 + 理解时间小于 \(40\) min
正片开始!
CF17A
题面(可从下方链接跳转看原题题面):
序言 & 结论:
签到题,直接做做完了
推理过程:
线性筛
直接枚举模拟即可
细节处理:
比对的过程不要下标越界捏!
代码:
点击查看代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1024;
int n,k,prime[maxn],cnt;
bool isprime[maxn];
inline void euler(){
memset(isprime,true,sizeof(isprime));
isprime[1]=false;
for(int i=2;i<=n;i++){
if(isprime[i]){
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
isprime[i*prime[j]]=false;
if(i%prime[j]==0){
break;
}
}
}
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
euler();
int tot=0;
for(int i=3;i<=cnt;i++){
for(int j=2;j<i;j++){
if(prime[j-1]+prime[j]+1==prime[i]){
tot++;
}
}
}
if(tot>=k){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
return 0;
}
完结撒花!
--------------------云落的分割线--------------------
CF17B
题面(可从下方链接跳转看原题题面):
序言 & 结论:
签到题 $ \times 2 $
推理过程:
这不直接最小生成树板子吗?
云落刚好昨天写了高效进阶最小生成树的题解呢!
细节处理:

代码:
点击查看代码
#include<iostream>
#include<algorithm>
const int maxn=1024,maxm=1e4+10;
using namespace std;
int n,m,a[maxn];
bool fa[maxn];
struct node{
int u,v,w;
friend bool operator < (const node &x,const node &y){
return x.w<y.w;
}
}e[maxm];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
cin>>m;
for(int i=1;i<=m;i++){
cin>>e[i].u>>e[i].v>>e[i].w;
}
sort(e+1,e+m+1);
int ans=0,cnt=0;
for(int i=1;i<=m;i++){
int x=e[i].u,y=e[i].v,z=e[i].w;
if(!fa[y]&&a[x]>a[y]){
fa[y]=true;
ans+=z;
cnt++;
}
if(cnt==n-1){
break;
}
}
if(cnt==n-1){
cout<<ans<<endl;
}else{
cout<<-1<<endl;
}
return 0;
}
完结撒花!
--------------------云落的分割线--------------------
CF17C
题面(可从下方链接跳转看原题题面):
序言 & 结论:
难度:紫题(建议降绿)
推理过程:
虚假的字符串,真实的 dp
钦定 $ f_{i,x,y,z} $ 表示前 $ i $ 个字符中有 $ x $ 个“a”,$ y $ 个“b”,$ z $ 个“c”
有转移方程:
其中 $ nxt_{i,0/1/2} $ 表示位置 $ i $ 上 $ a,b,c $ 下一个可拓展位置
细节处理:
这题卡空间
$ maxn=150+10 $ 会喜提 MLE
$ maxn=150+1 $ 会喜提 RE
二分答案得到 $ maxn=150+5 $,可以 AC 力!
代码:
点击查看代码
#include<iostream>
using namespace std;
const int maxn=155,maxl=55,mod=51123987;
int n;
string s;
int nxt[maxn][3],dp[maxn][maxl][maxl][maxl];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>s;
s=' '+s;
nxt[n+1][0]=n+1;
nxt[n+1][1]=n+1;
nxt[n+1][2]=n+1;
for(int i=n;i>=1;i--){
nxt[i][0]=nxt[i+1][0];
nxt[i][1]=nxt[i+1][1];
nxt[i][2]=nxt[i+1][2];
nxt[i][s[i]-'a']=i;
}
dp[1][0][0][0]=1;
int ans=0;
for(int i=1;i<=n;i++){
for(int x=0;x<=(n+2)/3;x++){
for(int y=0;y<=(n+2)/3;y++){
for(int z=0;z<=(n+2)/3;z++){
if(x+y+z==n&&abs(x-y)<=1&&abs(x-z)<=1&&abs(y-z)<=1){
ans=(ans+dp[i][x][y][z])%mod;
}
dp[nxt[i][0]][x+1][y][z]=(dp[nxt[i][0]][x+1][y][z]+dp[i][x][y][z])%mod;
dp[nxt[i][1]][x][y+1][z]=(dp[nxt[i][1]][x][y+1][z]+dp[i][x][y][z])%mod;
dp[nxt[i][2]][x][y][z+1]=(dp[nxt[i][2]][x][y][z+1]+dp[i][x][y][z])%mod;
}
}
}
}
cout<<ans<<endl;
return 0;
}
完结撒花!
--------------------云落的分割线--------------------
CF17D
题面(可从下方链接跳转看原题题面):
序言 & 结论:
难度:紫题?(扩展欧拉定理直接秒……)
推理过程:
形式化题意,求 $ x $ 的值,满足 $ (a-1) \times a^{n-1} \equiv x \bmod c $
注意到恐怖的数据范围,直接扩展欧拉定理安排上
有 $ a^{n-1} \equiv a^{(n-1) \bmod \phi (c) + \phi (c) } \bmod c $
然后就直接快速幂即可!
细节处理:

代码:
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
const int maxn=1e6+10;
char sb[maxn],sn[maxn];
int c;
bool flag;
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1){
res=res*a%c;
}
a=a*a%c;
b>>=1;
}
return res;
}
signed main(){
scanf("%s%s%lld",sb+1,sn+1,&c);
int tmp=c,phi=c;
int len1=strlen(sb+1),len2=strlen(sn+1);
for(int i=2;i*i<=tmp;i++){
if(tmp%i==0){
phi=phi/i*(i-1);
while(tmp%i==0){
tmp/=i;
}
}
}
if(tmp>1){
phi=phi/tmp*(tmp-1);
}
int b=0;
for(int i=1;i<=len1;i++){
b=(b*10+sb[i]-'0')%c;
}
for(int i=len2;i>=1;i--){
if(sn[i]=='0'){
sn[i]='9';
}else{
sn[i]--;
break;
}
}
int n=0;
bool flag=false;
for(int i=1;i<=len2;i++){
n=n*10+sn[i]-'0';
if(n>=phi){
flag=true;
}
n%=phi;
}
if(flag){
n+=phi;
}
int ans=((b-1)*qpow(b,n)%c+c)%c;
if(ans==0){
printf("%lld\n",c);
}else{
printf("%lld\n",ans);
}
return 0;
}
完结撒花!
--------------------云落的分割线--------------------
CF17E
题面(可从下方链接跳转看原题题面):
序言 & 结论:
难度:紫题(Manacher 模板变式?)
推理过程:
回文串直接 Manacher
钦定 $ f_i,g_i $ 分别表示以 $ i $ 为开头的回文串有多少个,以 $ i $ 为结尾的回文串有多少个
显然有 $ ans=\sum _{i=1} ^{n} f_i \sum _{j=1} ^{i-1} g_i $
前缀和维护 $ g_i $,差分维护 $ f_i $
细节处理:
关于云落马拉车数组没双倍空间虚空调试两个点这件事
代码:
点击查看代码
#pragma GCC optimize("Ofast,unroll-loops")
#include<iostream>
#include<cstdio>
#include<cstring>
#define int long long
using namespace std;
const int maxn=2e6+10,mod=51123987;
int n;
char a[maxn<<1],s[maxn<<1];
int r[maxn<<1],f[maxn<<1],g[maxn<<1],tot;
inline void init(){
s[0]='^';
s[n<<1|1]='%';
for(int i=1;i<=n;i++){
s[(i<<1)-1]='%';
s[i<<1]=a[i];
}
return;
}
inline void manacher(){
int p=0,mx=0;
for(int i=1;i<=(n<<1|1);i++){
if(i<mx){
r[i]=min(mx-i,r[(p<<1)-i]);
}else{
r[i]=1;
}
while(i-r[i]>=1&&i+r[i]<=(n<<1|1)&&s[i-r[i]]==s[i+r[i]]){
r[i]++;
}
if(i+r[i]>mx){
mx=i+r[i];
p=i;
}
tot=(tot+(r[i]>>1))%mod;
}
return;
}
signed main(){
scanf("%lld%s",&n,a+1);
init();
manacher();
for(int i=1;i<=((n<<1)|1);i++){
f[i-r[i]+1]++;
f[i+1]--;
g[i]++;
g[i+r[i]]--;
}
for(int i=1;i<=((n<<1)|1);i++){
f[i]+=f[i-1];
g[i]+=g[i-1];
}
int sum=0,ans=(tot-1)*tot/2%mod;
for(int i=2;i<=((n<<1)|1)-2;i+=2){
sum=(sum+g[i])%mod;
ans=(ans-sum*f[i+2]%mod+mod)%mod;
}
printf("%lld\n",ans);
return 0;
}
完结撒花!

浙公网安备 33010602011771号