A.珠
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/珠
题解:sb题,把原串复制一边接到后面然后来回扫两遍即可。
sb题还不能A,我是大sb,数组开小+只扫一遍=90
幸亏出题人数据良心T_T
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 200000+1000 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 inline int read() 25 { 26 int x=0,f=1;char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 29 return x*f; 30 } 31 int n,f[maxn]; 32 string s; 33 bool flag=0; 34 int main() 35 { 36 freopen("input.txt","r",stdin); 37 freopen("output.txt","w",stdout); 38 cin>>s; 39 s=s+s; 40 n=s.length()>>1; 41 memset(f,128,sizeof(f)); 42 for0(i,2*n-1) 43 if(s[i]=='2')f[i]=1,flag=1; 44 else if(s[i]=='3') 45 { 46 if(i==0)continue; 47 f[i]=f[i-1]+1; 48 } 49 int ans=0; 50 for0(i,2*n-1)ans=max(ans,min(f[i],n)); 51 memset(f,128,sizeof(f)); 52 for3(i,2*n-1,0) 53 if(s[i]=='2')f[i]=1,flag=1; 54 else if(s[i]=='3') 55 { 56 if(i==0)continue; 57 f[i]=f[i+1]+1; 58 } 59 for0(i,2*n-1)ans=max(ans,min(f[i],n)); 60 if(!flag)printf("TvT "); 61 else 62 { 63 printf("2"); 64 for1(i,ans-1)printf("3"); 65 printf(" "); 66 } 67 return 0; 68 }
B.兔农
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/免农
题解:刚开始看见题目给吓尿了,莫非真是noi2011的兔农?
后来想了想如何骗分:
1)k%p==0 直接输出0
2)n<=100W 暴力
3)貌似 k 是偶数直接上快速幂
4)好像 只要减少1只之后就不会减少了 break之后上快速幂
结果在最后1分钟交了就A了。。。rp。。。
而且这居然就是正解。。。乱搞啊。。。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 500+100 14 #define maxm 500+100 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 inline ll read() 25 { 26 ll x=0,f=1;char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 29 return x*f; 30 } 31 ll n,k,p; 32 ll power(ll x,ll y) 33 { 34 ll t=1; 35 for(;y;y>>=1,x=(x*x)%p) 36 if(y&1)t=(t*x)%p; 37 return t; 38 } 39 int main() 40 { 41 freopen("input.txt","r",stdin); 42 freopen("output.txt","w",stdout); 43 n=read();k=read();p=read(); 44 if(k%2==0)printf("%lld ",power(2,n+1)); 45 else if(k%p==0)printf("0 "); 46 else if(n<=5000000) 47 { 48 ll x=2%k,y=2%p; 49 for(ll i=1;i<=n;i++) 50 { 51 x=(x+x)%k; 52 y=(y+y)%p; 53 if(x==1)x=0,y=(y-1+p)%p; 54 } 55 printf("%lld ",y); 56 } 57 else 58 { 59 ll x=2%k,y=2%p,i=1; 60 for(i=1;i<=n;i++) 61 { 62 x=(x+x)%k; 63 y=(y+y)%p; 64 if(x==1){x=0;y=(y-1+p)%p;break;} 65 } 66 printf("%lld ",power(2,n-i)*y%p); 67 } 68 return 0; 69 }
C.高维网络
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2354%20-%20Streaming%20%235%20(NOIP模拟赛Day1)/高维网络
题解:首先从n维空间中一个点到另一个点(某一维不能往回走)的方案数就是一个多重集合的排列数。
然后问题就转化成了一个容斥原理。暴力容斥貌似能得80?让我们考虑满分算法:
我当时不知怎么想的就yy出了和题解一样的方法。。。
我的代码是这样的:
1 int l=0,r=1;q[1]=0;g[0]=-1; 2 while(l<r) 3 { 4 int x=q[++l]; 5 for1(i,m+1) 6 if(f[x][i]) 7 { 8 inp[i]--; 9 g[i]-=mul(g[x],f[x][i]); 10 g[i]=(g[i]%mod+mod)%mod; 11 if(!inp[i])q[++r]=i; 12 } 13 }
(mul是一个乘法函数,我不想都开long long 又怕爆int so。。。)
f[x][i]表示 x 到 i 的路径条数
貌似根据容斥原理很好懂?(其实是我说不清楚。。。)
我还是搬运题解吧:
设g[i]表示从点A到点i,不经过任何一个被破坏的点的路线条数。
设f[i][j]表示从点 i 到点 j 可以经过任意个被破坏的点的路线条数,那么
那么g[i]= f[A][i]−从点A到点 i ,经过了至少一个被破坏的点的路线条数。
枚举经过的第一个被破坏的点,那么
那么g[i]= f[A][i]-sigma(g[x]*f[x][i]) (x可达i)
最后 g[B]就是答案。
orzzzz
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 500+100 14 #define maxm 10000000+10 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define mod 1000000007 23 using namespace std; 24 inline int read() 25 { 26 int x=0,f=1;char ch=getchar(); 27 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 28 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 29 return x*f; 30 } 31 int n,m,b[maxn][maxn],mx,fac[maxm],g[maxn],inp[maxn],q[maxn],f[maxn][maxn]; 32 inline bool check(int x,int y) 33 { 34 for1(i,n)if(b[x][i]>b[y][i])return 0; 35 return 1; 36 } 37 ll power(ll x,ll y) 38 { 39 ll t=1; 40 for(;y;y>>=1,x=(x*x)%mod) 41 if(y&1)t=(t*x)%mod; 42 return t; 43 } 44 inline int mul(int x,int y) 45 { 46 ll xx=x,yy=y; 47 return (xx*yy)%mod; 48 } 49 inline ll dist(int x,int y) 50 { 51 ll t1=0,t2=1; 52 for1(i,n) 53 { 54 t1+=b[y][i]-b[x][i]; 55 t2=mul(t2,fac[b[y][i]-b[x][i]]); 56 } 57 t1=fac[t1]; 58 return t1*power(t2,mod-2)%mod; 59 } 60 int main() 61 { 62 freopen("input.txt","r",stdin); 63 freopen("output.txt","w",stdout); 64 n=read();m=read(); 65 for1(i,n) 66 { 67 b[m+1][i]=read(); 68 if(b[m+1][i]>mx)mx=b[m+1][i]; 69 } 70 mx*=n; 71 for1(i,m)for1(j,n)b[i][j]=read(); 72 fac[0]=1; 73 for1(i,mx)fac[i]=mul(fac[i-1],i); 74 for0(i,m) 75 for0(j,m+1) 76 if(i!=j) 77 if(check(i,j))f[i][j]=dist(i,j),inp[j]++; 78 int l=0,r=1;q[1]=0;g[0]=-1; 79 while(l<r) 80 { 81 int x=q[++l]; 82 for1(i,m+1) 83 if(f[x][i]) 84 { 85 inp[i]--; 86 g[i]-=mul(g[x],f[x][i]); 87 g[i]=(g[i]%mod+mod)%mod; 88 if(!inp[i])q[++r]=i; 89 } 90 } 91 printf("%d",g[m+1]); 92 return 0; 93 }
没AK感觉有点儿遗憾,不过RP已经是爆棚了。。。