CSP-S 模拟105


   小W的魔术

    总的方案数减去满意的方案数

    考虑s序列由原序列的两端拼合而成,或者就是两端中的一端

    先看由两端拼合的方案,确定序列有长度x的前缀与S的前缀相同,那么有长度为len-x的后缀与S的后缀相同

    为了不重不漏,序列的x+1的位置一定不等于S的x+1的位置,因为这种情况在 长度为x+1的前缀与S相同的情况会被考虑到,所以方案总数$25*26^{n-len-1}$

    枚举x发现x有len个(前缀就等于S也考虑进去),则方案数 $len*25*26^{n-len-1}$

    最后看后缀为S的方案,显然最后len为确定$26^{n-len}$,但是又因为当序列第一个字母等于S的第一个字母且后缀和S相同的情况会在x==1时考虑进去

    所以序列第一个字母确定,有25中情况,那后缀的方案数为$25*26^{n-len}$

    总方案 $26^n-25*26^{n-len-1}*len-25*26^{n-len}$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 long long n,len;
 6 char s[1100000];
 7 const long long mod=998244353;
 8 long long qpow(long long a,long long b){
 9     if(b<0) return 0;
10     long long ans=1;
11     a%=mod;
12     while(b){
13         if(b&1) ans=ans*a%mod;
14         b>>=1;
15         a=a*a%mod;
16     }
17     return ans;
18 }
19 int main(){
20     freopen("magic.in","r",stdin);
21     freopen("magic.out","w",stdout);
22     scanf("%lld%s",&n,s+1);
23     len=strlen(s+1);
24     long long ans=0;
25     ans=(ans+qpow(26,n-len-1)*25%mod*len%mod)%mod;
26     ans=(ans+qpow(26,n-len))%mod;
27     printf("%lld\n",(qpow(26,n)-ans+mod)%mod);
28 }
View Code


  小Y的图

    货车运输原题,最小生成树+树上倍增维护路径最大值 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 struct node{
 6     int l,r,z;
 7     bool operator < (const node b)const{
 8         return z<b.z;
 9     }
10 }e[310000];
11 int n,m,Q,ances[310000],fa[310000][20],maxn[310000][20],dis[310000];
12 int to[610000],nex[610000],head[310000],c[610000],tot;
13 int find(int x){return ances[x]==x?x:ances[x]=find(ances[x]);}
14 void add(int x,int y,int z){
15     to[++tot]=y,nex[tot]=head[x],head[x]=tot,c[tot]=z;
16 }
17 void dfs(int x,int pre){
18     dis[x]=dis[pre]+1;
19     fa[x][0]=pre;
20     for(register int i=1;i<=18;i++){
21         fa[x][i]=fa[fa[x][i-1]][i-1];
22         maxn[x][i]=max(maxn[x][i-1],maxn[fa[x][i-1]][i-1]);
23     }
24     for(register int i=head[x];i;i=nex[i]){
25         int y=to[i];
26         if(y==pre) continue;
27         maxn[y][0]=c[i];
28         dfs(y,x);
29     }
30 }
31 int lca(int x,int y){
32     if(dis[x]>dis[y]) swap(x,y);
33     int ans=0;
34     for(register int i=18;i>=0;i--){
35         if(dis[fa[y][i]]>=dis[x]){
36             ans=max(ans,maxn[y][i]);
37             y=fa[y][i];
38         }
39     }
40     if(x==y) return ans;
41     for(register int i=18;i>=0;i--){
42         if(fa[y][i]!=fa[x][i]){
43             ans=max(ans,maxn[y][i]);
44             ans=max(ans,maxn[x][i]);
45             y=fa[y][i];
46             x=fa[x][i];
47         }
48     }
49     return max(ans,max(maxn[x][0],maxn[y][0]));
50 }
51 int main(){
52     freopen("graph.in","r",stdin);
53     freopen("graph.out","w",stdout);
54     scanf("%d%d%d",&n,&m,&Q);
55     for(register int i=1;i<=m;i++)    scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].z);
56     sort(e+1,e+m+1);
57     for(register int i=1;i<=n;i++) ances[i]=i;
58     for(register int i=1;i<=m;i++){
59         int x=find(e[i].l),y=find(e[i].r);
60         if(x!=y){
61             add(e[i].l,e[i].r,e[i].z);
62             add(e[i].r,e[i].l,e[i].z);
63             ances[x]=y;
64         }
65     }
66     for(register int i=1;i<=n;i++){
67         if(!dis[i]){
68             dfs(i,0);
69         }
70     }
71     int x,y;
72     while(Q--){
73         scanf("%d%d",&x,&y);
74         if(find(x)!=find(y)) puts("-1");
75         else printf("%d\n",lca(x,y));
76     }
77 }
View Code

  小L的数

    答案一定小于等于4,因为任意一个数都可以由 01,02,04,08组成(每一位的数(0~9),都可以由0,1,2,4,8组成)

    验证1,2,3个喜欢的数的能否拼成,否则就是4

    从低到高枚举询问的数在该位的数字,三维DP f[i][j][k],表示第i位向下一位进0或1或2位,且有k(k<8)的状态表示三个数分别是否到最高位的方  案是否存在

    简单DP,最后看询问的最高位的进位为0是否存在即可

    在线求时间稍慢,大力卡常就好,大神yxs预处理碾压我

    

    

        

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define mu(x) ((x)<10?(x):((x)>=20?(x)-20:(x)-10))
 5 #define div(x) ((x)<10?0:((x)>=20?2:1))
 6 using namespace std;
 7 int T,a,b,c,d,u,v;
 8 char f[20][3][1<<3],p[20];
 9 long long now;
10 bool judge(){
11     memset(f,0,sizeof(f));
12     f[0][0][7]=1;
13     for(int t=1;t<=p[0];t++){
14         register int w=p[t],flag=0;
15         for(register int j=0;j<=2;j++){
16             if(f[t-1][j][1]||f[t-1][j][3]||f[t-1][j][5]||f[t-1][j][7]){
17                 if(mu(a+j)==w) f[t][div(a+j)][1]=1;
18                 if(mu(b+j)==w) f[t][div(b+j)][1]=1;
19             }
20             if(f[t-1][j][2]||f[t-1][j][3]||f[t-1][j][6]||f[t-1][j][7]){
21                 if(mu(c+j)==w) f[t][div(c+j)][2]=1;
22                 if(mu(d+j)==w) f[t][div(d+j)][2]=1;
23             }
24             if(f[t-1][j][4]||f[t-1][j][5]||f[t-1][j][6]||f[t-1][j][7]){
25                 if(mu(u+j)==w) f[t][div(u+j)][4]=1;
26                 if(mu(v+j)==w) f[t][div(v+j)][4]=1;
27             }
28             if(f[t-1][j][3]||f[t-1][j][7]){
29                 if(mu(a+c+j)==w) f[t][div(a+c+j)][3]=1;
30                 if(mu(a+d+j)==w) f[t][div(a+d+j)][3]=1;
31                 if(mu(b+c+j)==w) f[t][div(b+c+j)][3]=1;
32                 if(mu(b+d+j)==w) f[t][div(b+d+j)][3]=1;
33             }
34             if(f[t-1][j][5]||f[t-1][j][7]){
35                 if(mu(a+u+j)==w) f[t][div(a+u+j)][5]=1;
36                 if(mu(a+v+j)==w) f[t][div(a+v+j)][5]=1;
37                 if(mu(b+u+j)==w) f[t][div(b+u+j)][5]=1;
38                 if(mu(b+v+j)==w) f[t][div(b+v+j)][5]=1;
39             }
40             if(f[t-1][j][6]||f[t-1][j][7]){
41                 if(mu(c+u+j)==w) f[t][div(c+u+j)][6]=1;
42                 if(mu(c+v+j)==w) f[t][div(c+v+j)][6]=1;
43                 if(mu(d+u+j)==w) f[t][div(d+u+j)][6]=1;
44                 if(mu(d+v+j)==w) f[t][div(d+v+j)][6]=1;
45             }
46             if(f[t-1][j][7]){
47                 if(mu(a+c+u+j)==w) f[t][div(a+c+u+j)][7]=1;
48                 if(mu(a+c+v+j)==w) f[t][div(a+c+v+j)][7]=1;
49                 if(mu(a+d+u+j)==w) f[t][div(a+d+u+j)][7]=1;
50                 if(mu(a+d+v+j)==w) f[t][div(a+d+v+j)][7]=1;
51                 if(mu(b+c+u+j)==w) f[t][div(b+c+u+j)][7]=1;
52                 if(mu(b+c+v+j)==w) f[t][div(b+c+v+j)][7]=1;
53                 if(mu(b+d+u+j)==w) f[t][div(b+d+u+j)][7]=1;
54                 if(mu(b+d+v+j)==w) f[t][div(b+d+v+j)][7]=1;
55             }
56         }
57         if(!(f[t][0][1]+f[t][0][2]+f[t][0][3]+f[t][0][4]+f[t][0][5]+f[t][0][6]+f[t][0][7]+f[t][1][1]+f[t][1][2]+f[t][1][3]+f[t][1][4]+f[t][1][5]+f[t][1][6]+f[t][1][7]+f[t][2][1]+f[t][2][2]+f[t][2][3]+f[t][2][4]+f[t][2][5]+f[t][2][6]+f[t][2][7])) return 0;
58     }
59     for(register int i=1;i<=7;i++) if(f[p[0]][0][i]) return 1;
60     return 0;
61 }
62 int work(){
63     p[0]=0;
64     for(long long i=now;i;i/=10) p[++p[0]]=i%10;
65     for(a=0;a<=9;a++) for(b=a+(a!=0);b<=9;b++)
66         for(c=a;c<=9;c++) for(d=c+(c!=0);d<=9;d++)
67             for(u=c;u<=9;u++) for(v=u+(u!=0);v<=9;v++)
68                 if(judge()){
69                     int ans=0;
70                     if(a||b) ans++;
71                     if(c||d) ans++;
72                     if(u||v) ans++;
73                     return ans;
74                 }
75     return 0;
76 }
77 int main(){
78     freopen("number.in","r",stdin);
79     freopen("number.out","w",stdout);
80     scanf("%d",&T);
81     while(T--){
82         scanf("%lld",&now);
83         int ans=work();
84         if(ans) printf("%d\n",ans);
85         else puts("4");
86     }
87 }
View Code

猜你喜欢

转载自www.cnblogs.com/heoitys/p/11824507.html