zoukankan      html  css  js  c++  java
  • [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
    ",(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
    ",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 }
    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
    ",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 }
    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('
    ');
    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
    ",(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 }
    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
    ",(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
    ",(ans+MO)%MO);
    56 }
    57 int main(){
    58     T=gi();
    59     while(T--) work();
    60     return 0;
    61 }
    View Code

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

  • 相关阅读:
    【leetcode】1295. Find Numbers with Even Number of Digits
    【leetcode】427. Construct Quad Tree
    【leetcode】1240. Tiling a Rectangle with the Fewest Squares
    【leetcode】1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    【leetcode】1291. Sequential Digits
    【leetcode】1290. Convert Binary Number in a Linked List to Integer
    【leetcode】1269. Number of Ways to Stay in the Same Place After Some Steps
    【leetcode】1289. Minimum Falling Path Sum II
    【leetcode】1288. Remove Covered Intervals
    【leetcode】1287. Element Appearing More Than 25% In Sorted Array
  • 原文地址:https://www.cnblogs.com/Super-Nick/p/6596466.html
Copyright © 2011-2022 走看看