最近考了几次试,做完之后发现自己还是缺乏思维精度和深度……在此把一些奇怪的思路记下来……
随
题意大概就是拿了一堆数取来取去,这些数在一个模数意义下做乘法,求出操作后取值的期望。
首先,找到这个模数的原根(鬼知道为什么现在出来了),然后就把这些乘法变成加法,然后就是矩阵一通乱搞……
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1005,MOD=(int)1e9+7; 7 long long qpow(long long x,int tim,int Module) 8 { 9 long long tmp=1; 10 for(;tim;tim>>=1,x=x*x%Module) 11 if(tim&1)tmp=tmp*x%Module; 12 return tmp; 13 } 14 int getroot(int x) 15 { 16 for(int i=1;i<=x;i++) 17 { 18 int val=1;bool yes=1; 19 for(int j=1;j<x-1;j++) 20 { 21 val=val*1ll*i%x; 22 if(val==1) 23 { 24 yes=0; 25 break; 26 } 27 } 28 if(yes)return i; 29 } 30 } 31 int n,m,mod,powe[maxn],III[maxn],cnt[maxn],Probablities[33][maxn],f[2][maxn]; 32 void moduleadd(int &a,int b) 33 { 34 a+=b;if(a>MOD)a-=MOD; 35 } 36 int haha() 37 { 38 scanf("%d%d%d",&n,&m,&mod); 39 int rt=getroot(mod);powe[0]=1; 40 for(int i=1;i<=mod;i++)powe[i]=powe[i-1]*1ll*rt%mod; 41 int mod2=mod-1; 42 for(int i=0;i<mod2;i++)III[powe[i]]=i; 43 for(int i=1;i<=n;i++) 44 { 45 int x;scanf("%d",&x); 46 cnt[III[x]]++; 47 } 48 int Inv=qpow(n,MOD-2,MOD); 49 for(int i=0;i<mod2;i++)Probablities[0][i]=Inv*1ll*cnt[i]%MOD; 50 for(int i=1;i<=32;i++) 51 for(int j=0;j<mod2;j++) 52 for(int k=0;k<mod2;k++)moduleadd(Probablities[i][(j+k)%mod2],Probablities[i-1][j]*1ll*Probablities[i-1][k]%MOD); 53 f[0][0]=1; 54 for(int i=0;m;m>>=1,i++) 55 if(m&1) 56 { 57 for(int j=0;j<mod2;j++)f[1][j]=0; 58 for(int j=0;j<mod2;j++) 59 for(int k=0;k<mod2;k++)moduleadd(f[1][(k+j)%mod2],f[0][j]*1ll*Probablities[i][k]%MOD); 60 for(int j=0;j<mod2;j++)f[0][j]=f[1][j]; 61 } 62 int ans=0; 63 for(int i=0;i<mod2;i++)moduleadd(ans,f[0][i]*1ll*powe[i]%MOD); 64 printf("%d\n",ans); 65 } 66 int sb=haha(); 67 int main(){;}