20分特判,一个puts("1")一个快速幂,不讲。

50%算法:

上次就讲了,可是应该还是有像 xuefen某 或 Dybal某 一样没听的。

用a×inv(b)%mod来表示分数的时候,这个分数值可加可乘(有空证明)

像是一个dp题啊。

初状态是1方案数为1,然后做乘法转移不就好了嘛?

设dp[i][j]表示进行了i次操作后所得的值为j

dp[i][j*a[k]%mod]+=dp[i-1][j];

复杂度O(mod2×m)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 #include<string>
 8 #include<cstring>
 9 #define int long long
10 #define m(a) memset(a,0,sizeof(a))
11 #define AA cout<<"Alita"<<endl
12 using namespace std;
13 const int mod=1e9+7;
14 int ans,S,n,m,p,v[1050],a[100500],f[1050][1050],g[1050][1050],tmp[1050][1050];
15 int poww(int x,int y,int z)
16 {
17         int sum=1;
18         while(y)
19         {
20                 if(y&1) sum=sum*x%z;
21                 y>>=1;
22                 x=x*x%z;
23         }
24         return sum;
25 }
26 void X_g()
27 {
28         memset(tmp,0,sizeof(tmp));
29         for(int i=1;i<p;i++)
30         {
31                 for(int j=1;j<p;j++)
32                 {
33                         (tmp[1][i]+=g[1][j]*f[j][i]%mod)%=mod;
34                 }
35         }
36         for(int i=1;i<p;i++) 
37         {
38                 g[1][i]=tmp[1][i];
39         }
40 }
41 void X_f()
42 {
43         memset(tmp,0,sizeof(tmp));
44         for(int i=1;i<p;i++)
45         {
46                 for(int j=1;j<p;j++)
47                 {
48                         for(int k=1;k<p;k++)
49                         {
50                                 (tmp[i][j]+=f[i][k]*f[k][j]%mod)%=mod;
51                         }
52                 }
53         }
54         for(int i=1;i<p;i++)
55         {
56                 for(int j=1;j<p;j++)
57                 {
58                         f[i][j]=tmp[i][j];
59                 }
60         }
61 }
62 void work(int y)
63 {
64         while(y)
65         {
66                 if(y&1) X_g();
67                 y>>=1;
68                 X_f();
69         }
70 }
71 signed main()
72 {
73         //freopen("1.in","r",stdin);
74         //freopen("1.out","w",stdout);
75         scanf("%lld%lld%lld",&n,&m,&p);
76         if(p==2){puts("1");return 0;}
77         for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
78         if(n==1){printf("%lld",poww(a[1],m,p));return 0;}
79         S=poww(n,mod-2,mod);
80         for(int i=1;i<=n;i++)
81         {
82                 (v[a[i]%p]+=S)%=mod;
83         }
84         g[1][1]=1;
85         for(int j=1;j<p;j++)
86         {
87                 for(int k=1;k<p;k++)
88                 {
89                         f[j][j*k%p]+=v[k];
90                 }
91         }
92         work(m);
93         for(int i=1;i<p;i++)
94         {
95                 (ans+=g[1][i]*i%mod)%=mod;
96         }
97         printf("%lld",ans);
98         return 0;
99 }
Dybala的50分代码(已征得同意后转载)

相关文章:

  • 2022-12-23
  • 2021-11-04
  • 2022-02-17
  • 2021-12-19
  • 2021-12-29
  • 2022-12-23
  • 2021-06-23
猜你喜欢
  • 2022-01-22
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-13
  • 2021-04-11
相关资源
相似解决方案