[2017.3.20]矩阵总结

终于把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\n",(ans+k)%k);
111 }
112 int main(){
113     work();
114     return 0;
115 }
View Code

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\n",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\n",ljq.rix[1][ed]);
223  
224 }
225  
226 int main(){
227  
228     work();
229  
230     return 0;
231  
232 }
View Code

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\n",y,y);return;}
 94 
 95     if(n<=2){printf("-1\n");return;}
 96 
 97     if(n==3){printf("%d %d\n",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\n",((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 }
View Code

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('\n');
186 
187     }
188 
189 }
190 
191 int main(){
192 
193     work();
194 
195     return 0;
196 
197 }
View Code

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\n",(ans+MO)%MO);
163     else        printf("0\n");
164     /*for (RG int i=1;i<=n&&!flag;++i)
165     if(fa[i]!=fa[i-1])
166         flag=1;
167         printf("%d\n",flag?0:(ans+MO)%MO);*/
168 }
169 int main(){
170     work();
171     return 0;
172 }
View Code

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\n",(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 }
View Code

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\n",(ans+MO)%MO);
56 }
57 int main(){
58     T=gi();
59     while(T--) work();
60     return 0;
61 }
View Code

总的来说,数论题难写难调,还有很多要学的。

posted @ 2017-03-21 20:22  Super_Nick  阅读(149)  评论(0编辑  收藏  举报