终于把WG的矩阵题除了NTT的序列统计其他都A啦----我个蒟蒻现在才A完
1.GT考试(bzoj1009)
主要是DP难推,难理解。一定要记得数列不唯一,DP的意思就是选择性。
好的题解:http://blog.csdn.net/cjk_cjk/article/details/43038377
1 /************************************************************** 2 Problem: 1009 3 User: Super_Nick 4 Language: C++ 5 Result: Accepted 6 Time:92 ms 7 Memory:1300 kb 8 ****************************************************************/ 9 10 #include<cmath> 11 #include<queue> 12 #include<cstdio> 13 #include<vector> 14 #include<cstdlib> 15 #include<cstring> 16 #include<iostream> 17 #include<algorithm> 18 #define RG register 19 #define M 21 20 #define K 1010 21 #define N 1000000010 22 #define inf 0x3f3f3f3f 23 #define Inf 99999999999999999LL 24 using namespace std; 25 typedef unsigned long long LL; 26 struct node{ 27 LL mat[M][M]; 28 }st,th; 29 LL nu; 30 LL n,m,k,ans,nex[M],num[M],last[11]; 31 inline int Abs(RG const int &a){return a>0?a:-a;} 32 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;} 33 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;} 34 inline LL gi(){ 35 RG LL x=0;RG bool flag=0;RG char c=getchar(); 36 while((c<'0'||c>'9')&&c!='-') c=getchar(); 37 if(c=='-') c=getchar(),flag=1; 38 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 39 return flag?-x:x; 40 } 41 inline LL gll(){ 42 RG LL x=0;RG bool flag=0;RG char c=getchar(); 43 while((c<'0'||c>'9')&&c!='-') c=getchar(); 44 if(c=='-') c=getchar(),flag=1; 45 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 46 return flag?-x:x; 47 } 48 inline node mult(RG node &a,RG node &b){ 49 RG node res; 50 memset(res.mat,0,sizeof(res.mat)); 51 for (RG LL i=0;i<=m;++i) 52 for (RG LL j=0;j<=m;++j) 53 for (RG LL ii=0;ii<=m;++ii) 54 res.mat[i][j]=(res.mat[i][j]+(a.mat[i][ii]*b.mat[ii][j])%k)%k; 55 return res; 56 } 57 inline void q_pow(RG LL lim){ 58 while(lim){ 59 if(lim&1) st=mult(st,th); 60 lim>>=1; 61 th=mult(th,th); 62 } 63 } 64 inline void work(){ 65 n=gi();m=gi();k=gi();nu=gll(); 66 //cout<<nu<<endl; 67 for (RG LL i=m;i;--i){num[i]=nu%10;nu/=10;} 68 /*for (RG int i=1;i<=m;++i) cout<<num[i]<<' '; 69 cout<<endl;*/ 70 for (RG LL i=2;i<=m;++i){ 71 RG LL j=nex[i-1]; 72 while(num[i]!=num[j+1]&&j) j=nex[j]; 73 if(num[i]==num[j+1]) nex[i]=j+1; 74 } 75 /*for (RG int i=1;i<=m;++i) cout<<nex[i]<<' '; 76 cout<<endl;*/ 77 st.mat[0][0]=1; 78 for (RG LL i=1;i<=m;++i){ 79 RG LL j=i-1,sum=0; 80 while(j){ 81 if(last[num[j+1]]!=i){ 82 th.mat[i-1][j+1]=1; 83 last[num[j+1]]=i; 84 ++sum; 85 } 86 j=nex[j]; 87 } 88 if(last[num[j+1]]!=i){ 89 th.mat[i-1][j+1]=1; 90 last[num[j+1]]=i; 91 ++sum; 92 } 93 th.mat[i-1][0]=10-sum; 94 //cout<<th.mat[i-1][0]<<endl; 95 } 96 /*for (int i=0;i<=m;++i){ 97 for (int j=0;j<=m;++j) 98 cout<<st.mat[i][j]<<' '; 99 cout<<endl; 100 } 101 cout<<endl; 102 for (int i=0;i<=m;++i){ 103 for (int j=0;j<=m;++j) 104 cout<<th.mat[i][j]<<' '; 105 cout<<endl; 106 }*/ 107 q_pow(n); 108 for (RG LL i=0;i<m;++i) 109 ans=(ans+st.mat[0][i])%k; 110 printf("%d ",(ans+k)%k); 111 } 112 int main(){ 113 work(); 114 return 0; 115 }
2.沼泽鳄鱼(bzoj1898)
关于食人鱼,因为1,2,3,4的LCM=12,所以分成12个矩阵一起,最后几个暴力搞就好了
1 /************************************************************** 2 Problem: 1898 3 User: Super_Nick 4 Language: C++ 5 Result: Accepted 6 Time:328 ms 7 Memory:1444 kb 8 ****************************************************************/ 9 10 #include<cmath> 11 12 #include<queue> 13 14 #include<cstdio> 15 16 #include<vector> 17 18 #include<cstdlib> 19 20 #include<cstring> 21 22 #include<iostream> 23 24 #include<algorithm> 25 26 #define N 51 27 28 #define F 21 29 30 #define K 2000000010 31 32 #define MO 10000 33 34 #define RG register 35 36 #define inf 0x3f3f3f3f 37 38 #define Inf 99999999999999999LL 39 40 using namespace std; 41 42 typedef long long LL; 43 44 struct node{ 45 46 int rix[N][N]; 47 48 }mat[13],matrix,ljq; 49 50 int k,m,n,x,y,T,ed,st,nfish,p[4]; 51 52 inline int Abs(RG const int &a){return a>0?a:-a;} 53 54 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;} 55 56 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;} 57 58 inline int gi(){ 59 60 RG int x=0;RG bool flag=0;RG char c=getchar(); 61 62 while((c<'0'||c>'9')&&c!='-') c=getchar(); 63 64 if(c=='-') c=getchar(),flag=1; 65 66 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 67 68 return flag?-x:x; 69 70 } 71 72 inline void print(RG node &a){ 73 74 for (RG int i=1;i<=n;++i){ 75 76 for (RG int j=1;j<=n;++j) 77 78 cout<<a.rix[i][j]<<' '; 79 80 cout<<endl; 81 82 } 83 84 cout<<endl; 85 86 } 87 88 inline node mult(node &a,node &b){ 89 90 node res; 91 92 memset(res.rix,0,sizeof(res.rix)); 93 94 for (RG int i=1;i<=n;++i) 95 96 for (RG int j=1;j<=n;++j) 97 98 for (RG int ii=1;ii<=n;++ii) 99 100 res.rix[i][j]=(res.rix[i][j]+(a.rix[i][ii]*b.rix[ii][j])%MO)%MO; 101 102 return res; 103 104 } 105 106 inline node multt(node &a,node &b){ 107 108 node res; 109 110 memset(res.rix,0,sizeof(res.rix)); 111 112 for (RG int i=1;i<=n;++i) 113 114 for (RG int j=1;j<=n;++j) 115 116 for (RG int ii=1;ii<=n;++ii){ 117 118 printf("i=%d j=%d ii=%d a.rix[i][ii]=%d b.rix[ii][j]=%d ",i,j,ii,a.rix[i][ii],b.rix[ii][j]); 119 120 if(a.rix[i][ii]&&b.rix[ii][j]) cout<<"flag"<<endl; 121 122 res.rix[i][j]=(res.rix[i][j]+(a.rix[i][ii]*b.rix[ii][j])%MO)%MO; 123 124 } 125 126 return res; 127 128 } 129 130 inline void q_pow(RG int lim){ 131 132 /*RG node ans; 133 134 for (RG int i=1;i<=n;++i) 135 136 for (RG int j=1;j<=n;++j) 137 138 ans.rix[i][j]=(i==j);*/ 139 140 while(lim){ 141 142 if(lim&1) ljq=mult(ljq,matrix); 143 144 lim>>=1; 145 146 matrix=mult(matrix,matrix); 147 148 } 149 150 } 151 152 inline void work(){ 153 154 n=gi();m=gi();st=gi()+1;ed=gi()+1;k=gi(); 155 156 ljq.rix[1][st]=1; 157 158 for (RG int i=1;i<=m;++i){ 159 160 x=gi()+1;y=gi()+1; 161 162 mat[1].rix[x][y]=mat[1].rix[y][x]=1; 163 164 } 165 166 //print(mat[1]); 167 168 for (RG int i=2;i<=12;++i) mat[i]=mat[1]; 169 170 nfish=gi(); 171 172 for (RG int i=1;i<=nfish;++i){ 173 174 T=gi();p[0]=gi()+1;p[1]=gi()+1; 175 176 if(T>2){p[2]=gi()+1;if(T>3) p[3]=gi()+1;} 177 178 for (RG int j=1;j<=12;j+=T) 179 180 for (RG int ii=0;ii<T;++ii) 181 182 for (RG int jj=1;jj<=n;++jj) 183 184 mat[j+ii].rix[jj][p[(ii+1)%T]]=0; 185 186 } 187 188 //for (RG int i=1;i<=12;++i) 189 190 // print(mat[i]); 191 192 matrix=mat[1]; 193 194 for (RG int i=2;i<=12;++i) 195 196 //print(matrix);print(mat[i]); 197 198 matrix=mult(matrix,mat[i]); 199 200 //print(matrix); 201 202 q_pow(k/12); 203 204 //print(ljq); 205 206 //if(k%12) 207 208 for (RG int i=1;i<=k%12;++i) 209 210 //print(mat[i]); 211 212 ljq=mult(ljq,mat[i]); 213 214 //print(ljq); 215 216 //print(ljq); 217 218 //ljq.rix[1][st]=1; 219 220 //ljq=mult(ljq,matrix); 221 222 printf("%d ",ljq.rix[1][ed]); 223 224 } 225 226 int main(){ 227 228 work(); 229 230 return 0; 231 232 }
3.三角恒等变换
打表找规律
1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #include<cstring> 6 7 #include<iostream> 8 9 #include<algorithm> 10 11 #define Y 2000010 12 13 #define N 1000000007 14 15 #define MO 1000000007 16 17 #define RG register 18 19 using namespace std; 20 21 typedef long long LL; 22 23 struct node1{int rix[4];}mat1; 24 25 struct node2{int rix[4][4];}mat2; 26 27 int l,n,r,y,a[4]; 28 29 inline int gi(){ 30 31 RG int x=0;RG char c=getchar(); 32 33 while(c<'0'||c>'9') c=getchar(); 34 35 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 36 37 return x; 38 39 } 40 41 inline node1 mul(RG node1 &a,RG node2 &b){ 42 43 RG node1 res; 44 45 memset(res.rix,0,sizeof(res.rix)); 46 47 for (RG int i=1;i<=3;++i) 48 49 for (RG int j=1;j<=3;++j) 50 51 res.rix[i]=((LL)res.rix[i]+((LL)a.rix[j]*(LL)b.rix[j][i])%MO)%MO; 52 53 return res; 54 55 } 56 57 inline node2 mult(RG node2 &a,RG node2 &b){ 58 59 RG node2 res; 60 61 memset(res.rix,0,sizeof(res.rix)); 62 63 for (RG int i=1;i<=3;++i) 64 65 for (RG int j=1;j<=3;++j) 66 67 for (RG int ii=1;ii<=3;++ii) 68 69 res.rix[i][j]=((LL)res.rix[i][j]+((LL)a.rix[i][ii]*(LL)b.rix[ii][j])%MO)%MO; 70 71 return res; 72 73 } 74 75 inline void q_pow(RG int lim){ 76 77 while(lim){ 78 79 if(lim&1) mat1=mul(mat1,mat2); 80 81 lim>>=1; 82 83 mat2=mult(mat2,mat2); 84 85 } 86 87 } 88 89 inline void work(){ 90 91 y=gi();n=gi(); 92 93 if(n==0){printf("%d %d ",y,y);return;} 94 95 if(n<=2){printf("-1 ");return;} 96 97 if(n==3){printf("%d %d ",y+1,2*y-1);return;} 98 99 mat1.rix[1]=2*y-1; 100 101 mat1.rix[2]=y+mat1.rix[1]-1; 102 103 mat1.rix[3]=1; 104 105 mat2.rix[3][2]=-1; 106 107 mat2.rix[1][2]=mat2.rix[2][1]=mat2.rix[2][2]=mat2.rix[3][3]=1; 108 109 if(n>4) q_pow(n-4); 110 111 printf("%d %d ",((mat1.rix[1]+1)%MO+MO)%MO,(mat1.rix[2]+MO)%MO); 112 113 } 114 115 int main(){ 116 117 work(); 118 119 return 0; 120 121 }
4.矩阵幂之和
类似二分的思想……在CJOJ可以过在POJT了……Wander Why
1 #include<cmath> 2 3 #include<queue> 4 5 #include<cstdio> 6 7 #include<vector> 8 9 #include<cstdlib> 10 11 #include<cstring> 12 13 #include<iostream> 14 15 #include<algorithm> 16 17 #define N 31 18 19 #define eps (0.5) 20 21 #define RG register 22 23 #define inf 0x3f3f3f3f 24 25 #define K 10000000010LL 26 27 #define M 1000000000000000000LL 28 29 #define Inf 99999999999999999LL 30 31 using namespace std; 32 33 typedef unsigned long long LL; 34 35 int n; 36 37 LL m,k; 38 39 struct node{ 40 41 LL rix[N][N]; 42 43 }mat,ori; 44 45 inline int Abs(RG const int &a){return a>0?a:-a;} 46 47 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;} 48 49 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;} 50 51 inline void print(RG node &a){ 52 53 for (RG int i=1;i<=n;++i){ 54 55 for (RG int j=1;j<=n;++j) 56 57 cout<<a.rix[i][j]<<' '; 58 59 cout<<endl; 60 61 } 62 63 } 64 65 inline int gi(){ 66 67 RG int x=0;RG bool flag=0;RG char c=getchar(); 68 69 while((c<'0'||c>'9')&&c!='-') c=getchar(); 70 71 if(c=='-') c=getchar(),flag=1; 72 73 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 74 75 return flag?-x:x; 76 77 } 78 79 inline LL gll(){ 80 81 RG LL x=0;RG bool flag=0;RG char c=getchar(); 82 83 while((c<'0'||c>'9')&&c!='-') c=getchar(); 84 85 if(c=='-') c=getchar(),flag=1; 86 87 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 88 89 return flag?-x:x; 90 91 } 92 93 inline LL mul(RG LL a,RG LL b){ 94 95 return (a*b-(LL)((long double)a/m*(long double)b+eps)*m+m)%m; 96 97 } 98 99 inline node mplus(RG node a,RG node b){ 100 101 RG node res; 102 103 for (RG int i=1;i<=n;++i) 104 105 for (RG int j=1;j<=n;++j) 106 107 res.rix[i][j]=(a.rix[i][j]+b.rix[i][j])%m; 108 109 return res; 110 111 } 112 113 inline node mult(RG node a,RG node b){ 114 115 RG node res; 116 117 memset(res.rix,0,sizeof(res.rix)); 118 119 for (RG int i=1;i<=n;++i) 120 121 for (RG int j=1;j<=n;++j) 122 123 for (RG int ii=1;ii<=n;++ii) 124 125 res.rix[i][j]=(res.rix[i][j]+mul(a.rix[i][ii],b.rix[ii][j]))%m; 126 127 return res; 128 129 } 130 131 inline node q_pow(RG node a,RG LL lim){ 132 133 RG node ans; 134 135 memset(ans.rix,0,sizeof(ans.rix)); 136 137 for (RG int i=1;i<=n;++i) ans.rix[i][i]=1; 138 139 while(lim){ 140 141 if(lim&1) ans=mult(ans,a); 142 143 lim>>=1; 144 145 a=mult(a,a); 146 147 } 148 149 return ans; 150 151 } 152 153 inline void dfs(RG LL now){ 154 155 if(now==1) return; 156 157 dfs(now/2); 158 159 mat= mplus ( mat, mult( mat, q_pow (ori,now/2) ) ); 160 161 if(now&1) mat=mplus(mat,q_pow(ori,now)); 162 163 } 164 165 inline void work(){ 166 167 n=gi();k=gll();m=gll(); 168 169 for (RG int i=1;i<=n;++i) 170 171 for (RG int j=1;j<=n;++j) 172 173 ori.rix[i][j]=mat.rix[i][j]=gll()%m; 174 175 //print(ori);print(mat); 176 177 dfs(k); 178 179 for (RG int i=1;i<=n;++i){ 180 181 for (RG int j=1;j<=n;++j) 182 183 printf("%lld ",(mat.rix[i][j]+m)%m); 184 185 putchar(' '); 186 187 } 188 189 } 190 191 int main(){ 192 193 work(); 194 195 return 0; 196 197 }
5.最小生成树计数(bzoj1016)
暴力可以A好气哦。用MatrixTree定理,针对Dijikstra每一步每个连通块算一次生成树个数,再乘法原理。细节多。
1 /************************************************************** 2 Problem: 1016 3 User: Super_Nick 4 Language: C++ 5 Result: Accepted 6 Time:12 ms 7 Memory:1448 kb 8 ****************************************************************/ 9 10 #include<cmath> 11 #include<queue> 12 #include<cstdio> 13 #include<vector> 14 #include<cstdlib> 15 #include<cstring> 16 #include<iostream> 17 #include<algorithm> 18 #define N 110 19 #define M 1010 20 #define MO 31011 21 #define RG register 22 #define inf 0x3f3f3f3f 23 #define Inf 99999999999999999LL 24 using namespace std; 25 typedef long long LL; 26 struct node{ 27 int from,to,w; 28 }e[M]; 29 bool vis[N]; 30 int a,b,m,n,ans=1,flag,fa[N],col[N],kir[N][N],mat[N][N],kuai[N][N]; 31 inline int Abs(RG const int &a){return a>0?a:-a;} 32 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;} 33 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;} 34 inline int gi(){ 35 RG int x=0;RG bool flag=0;RG char c=getchar(); 36 while((c<'0'||c>'9')&&c!='-') c=getchar(); 37 if(c=='-') c=getchar(),flag=1; 38 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 39 return flag?-x:x; 40 } 41 inline bool cmp(RG const node &a,RG const node &b){ 42 //if(a.w==b.w){ 43 // if(a.from==b.from) 44 // return a.to<b.to; 45 // return a.from<b.from; 46 //} 47 return a.w<b.w; 48 } 49 inline int find(RG int x){return col[x]==x?x:find(col[x]);} 50 inline int found(RG int x){return fa[x]==x?x:found(fa[x]);} 51 inline int matrix_tree(RG int size){ 52 for (RG int i=1;i<=size;++i) 53 for (RG int j=1;j<=size;++j) 54 kir[i][j]%=MO; 55 RG int ret=1; 56 for(RG int j=2;j<=size;++j){ 57 for(RG int i=j+1;i<=size;++i) 58 while(kir[i][j]){ 59 RG int now=kir[j][j]/kir[i][j]; 60 for(RG int k=j;k<=size;++k){ 61 kir[j][k]=(kir[j][k]-(now*kir[i][k])%MO)%MO; 62 swap(kir[i][k],kir[j][k]); 63 } 64 ret*=-1; 65 } 66 //if(kir[j][j]==0) return 0; 67 ret=ret*kir[j][j]%MO; 68 } 69 return (ret+MO)%MO; 70 } 71 inline void kruskal(){ 72 for (RG int i=1;i<=m+1;++i){ 73 //cout<<i<<' '<<e[i].from<<' '<<e[i].to<<' '<<e[i].w<<endl; 74 if((i>1&&e[i].w>e[i-1].w)||i>m){ 75 for (RG int j=1;j<=n;++j) 76 if(vis[j]){ 77 a=found(j); 78 kuai[a][++kuai[a][0]]=j; 79 vis[j]=0; 80 } 81 /*for (RG int ii=1;ii<=n;++ii){ 82 for (RG int jj=1;jj<=n;++jj) 83 cout<<du[ii][jj]<<' '; 84 cout<<endl; 85 } 86 cout<<endl; 87 for (RG int ii=1;ii<=n;++ii){ 88 for (RG int jj=1;jj<=n;++jj) 89 cout<<mat[ii][jj]<<' '; 90 cout<<endl; 91 } 92 cout<<endl;*/ 93 for (RG int j=1;j<=n;++j) 94 if(kuai[j][0]>1){ 95 for (RG int i=2;i<=n;++i) 96 for (RG int j=2;j<=n;++j) 97 kir[i][j]=0; 98 //cout<<"hh="<<kuai[j][0]<<endl; 99 for (RG int ii=1;ii<=kuai[j][0];++ii) 100 for (RG int jj=ii+1;jj<=kuai[j][0];++jj){ 101 int a1=kuai[j][ii]; 102 int b1=kuai[j][jj]; 103 //cout<<"gt"<<a1<<' '<<b1<<' '<<ii-1<<' '<<jj-1<<' '<<mat[a1][b1]<<endl;//' '<<ii<<' '<<jj<<endl; 104 //cout<<"wg"<<kir[ii][jj]<<' '<<kir[jj][ii]<<' '<<kir[ii][ii]<<' '<<kir[jj][jj]<<endl; 105 kir[ii][jj]=(kir[jj][ii]-=mat[a1][b1]); 106 //kir[jj][ii]-=mat[a1][b1]; 107 //cout<<"omg"<<kir[jj][ii]<<' '<<kir[ii][jj]<<endl; 108 kir[ii][ii]+=mat[a1][b1]; 109 kir[jj][jj]+=mat[a1][b1]; 110 //cout<<kir[ii][jj]<<' '<<kir[jj][ii]<<' '<<kir[ii][ii]<<' '<<kir[jj][jj]<<endl; 111 } 112 /*cout<<endl; 113 for (RG int ii=1;ii<=kuai[j][0];++ii){ 114 for (RG int jj=1;jj<=kuai[j][0];++jj) 115 cout<<kir[ii][jj]<<' '; 116 cout<<endl; 117 }*/ 118 ans=(ans*matrix_tree(kuai[j][0]))%MO; 119 //cout<<"ans="<<ans<<endl; 120 for (RG int ii=1;ii<=kuai[j][0];++ii) 121 col[kuai[j][ii]]=j; 122 } 123 memset(kuai,0,sizeof(kuai)); 124 flag=0; 125 for(RG int j=1;j<=n;++j){ 126 col[j]=fa[j]=find(j); 127 if(col[j]==j) ++flag; 128 } 129 //if(i>m) break; 130 if(i>m||flag==1) return; 131 /*cout<<"hesitate"<<endl; 132 for(RG int i=1;i<=n;++i) 133 cout<<fa[i]<<' '; 134 cout<<endl;*/ 135 } 136 a=find(e[i].from),b=find(e[i].to); 137 //cout<<a<<' '<<b<<endl; 138 if(a==b) continue; 139 ++mat[a][b]; 140 ++mat[b][a]; 141 vis[a]=vis[b]=1; 142 //cout<<found(a)<<' '<<found(b)<<endl; 143 fa[found(b)]=found(a); 144 } 145 } 146 inline void work(){ 147 n=gi();m=gi(); 148 for (RG int i=1;i<=n;++i) 149 col[i]=fa[i]=i; 150 for (RG int i=1;i<=m;++i){ 151 e[i].from=gi(); 152 e[i].to=gi(); 153 //if(e[i].from>e[i].to) 154 //swap(e[i].to,e[i].from); 155 e[i].w=gi(); 156 } 157 sort(e+1,e+m+1,cmp); 158 //for (RG int i=1;i<=m;++i) 159 //cout<<e[i].from<<' '<<e[i].to<<' '<<e[i].w<<endl; 160 //cout<<endl; 161 kruskal(); 162 if(flag==1) printf("%d ",(ans+MO)%MO); 163 else printf("0 "); 164 /*for (RG int i=1;i<=n&&!flag;++i) 165 if(fa[i]!=fa[i-1]) 166 flag=1; 167 printf("%d ",flag?0:(ans+MO)%MO);*/ 168 } 169 int main(){ 170 work(); 171 return 0; 172 }
6.序列统计(bzoj4403)
知道Lucas就很水了…………关键要发现和杨辉三角的关系
好的题解:http://www.cnblogs.com/fenghaoran/p/6592128.html
1 /************************************************************** 2 Problem: 4403 3 User: Super_Nick 4 Language: C++ 5 Result: Accepted 6 Time:1000 ms 7 Memory:16916 kb 8 ****************************************************************/ 9 10 #include<cmath> 11 #include<queue> 12 #include<cstdio> 13 #include<vector> 14 #include<cstdlib> 15 #include<cstring> 16 #include<iostream> 17 #include<algorithm> 18 #define eps (0.5) 19 #define MO 1000003 20 #define RG register 21 #define N 1000000010 22 #define inf 0x3f3f3f3f 23 #define Inf 99999999999999999LL 24 using namespace std; 25 typedef unsigned long long LL; 26 int T,l,m,n,r; 27 LL jc[MO+1],ny[MO+1]; 28 /*inline int Abs(RG const int &a){return a>0?a:-a;} 29 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;} 30 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;}*/ 31 inline int gi(){ 32 RG int x=0;RG bool flag=0;RG char c=getchar(); 33 while((c<'0'||c>'9')&&c!='-') c=getchar(); 34 if(c=='-') c=getchar(),flag=1; 35 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 36 return flag?-x:x; 37 } 38 inline LL fbc(RG LL a,RG LL b){return (a*b-(LL)((long double)a/MO*(long double)b+eps)*MO+MO)%MO;} 39 inline LL coc(RG int a,RG int b){ 40 if(a<b) return 0; 41 //cout<<"C calc "<<a<<' '<<b<<' '<<jc[a]<<' '<<ny[jc[b]]<<' '<<ny[jc[a-b]]<<endl; 42 return fbc(fbc(jc[a],ny[jc[b]])%MO,ny[jc[a-b]])%MO; 43 } 44 inline LL lucas(RG int a,RG int b){ 45 if(b==0) return 1; 46 //cout<<"Lucas "<<a<<' '<<b<<' '<<coc(a%MO,b%MO)<<endl; 47 return fbc(coc((a+MO)%MO,(b+MO)%MO),lucas(a/MO,b/MO))%MO; 48 } 49 inline void work(){ 50 n=gi();l=gi();r=gi();m=r-l+1; 51 //cout<<n<<' '<<m<<endl; 52 printf("%lld ",(lucas(n+m,m)-1+MO)%MO); 53 } 54 int main(){ 55 jc[0]=ny[1]=1; 56 for (RG int i=1;i<=MO;++i) 57 jc[i]=((jc[i-1]*i)%MO+MO)%MO; 58 for (RG int i=2;i<=MO;++i) 59 ny[i]=(MO-(MO/i)*ny[MO%i]%MO+MO)%MO; 60 //cout<<ny[2]<<' '<<MO/2<<endl; 61 T=gi(); 62 while(T--) work(); 63 return 0; 64 }
7.Unkown Treasure
中国剩余定理+Lucas板子
1 #include<cmath> 2 #include<queue> 3 #include<cstdio> 4 #include<vector> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<algorithm> 9 #define RG register 10 #define LM 10001000 11 #define inf 0x3f3f3f3f 12 #define Inf 99999999999999999LL 13 using namespace std; 14 typedef long long LL; 15 LL T,k,b[11],p[11]; 16 LL MO,m,n,mo,ans,jc[11][LM+1],ny[11][LM+1]; 17 inline LL gi(){ 18 RG LL x=0;RG bool flag=0;RG char c=getchar(); 19 while((c<'0'||c>'9')&&c!='-') c=getchar(); 20 if(c=='-') c=getchar(),flag=1; 21 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 22 return flag?-x:x; 23 } 24 inline LL gll(){ 25 RG LL x=0;RG bool flag=0;RG char c=getchar(); 26 while((c<'0'||c>'9')&&c!='-') c=getchar(); 27 if(c=='-') c=getchar(),flag=1; 28 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 29 return flag?-x:x; 30 } 31 inline LL fbc(RG LL a,RG LL b,RG LL mod){return (a*b-(LL)((double)a/mod*(double)b)*mod+mod)%mod;} 32 inline LL cal(RG LL a,RG LL b,RG LL num){ 33 if(a<b) return 0; 34 return ((jc[num][a]*ny[num][jc[num][b]])%p[num]*ny[num][jc[num][a-b]])%p[num]; 35 } 36 inline LL lucas(RG LL a,RG LL b,RG LL num){ 37 if(b==0) return 1; 38 return cal(a%p[num],b%p[num],num)*lucas(a/p[num],b/p[num],num)%p[num]; 39 } 40 inline void work(){ 41 n=gll();m=gll();k=gi();MO=1;ans=0; 42 for (RG LL i=1;i<=k;++i){ 43 p[i]=gi();MO*=p[i]; 44 ny[i][1]=jc[i][0]=1; 45 for (RG LL j=1;j<=p[i];++j) 46 jc[i][j]=(jc[i][j-1]*j%p[i]+p[i])%p[i]; 47 for (RG LL j=2;j<=p[i];++j) 48 ny[i][j]=(p[i]-(p[i]/j)*ny[i][p[i]%j])%p[i]; 49 b[i]=lucas(n,m,i)%p[i]; 50 } 51 for (RG LL i=1;i<=k;++i){ 52 mo=MO/p[i]; 53 ans=(ans+ fbc( fbc((LL)ny[i][mo%p[i]],mo,MO) ,b[i],MO) )%MO; 54 } 55 printf("%lld ",(ans+MO)%MO); 56 } 57 int main(){ 58 T=gi(); 59 while(T--) work(); 60 return 0; 61 }
总的来说,数论题难写难调,还有很多要学的。