「luogu3702」[SDOI2017]序列计数

考虑题目中的两个限制:

  • 至少有一个数是质数:简单容斥,至少有一个数是质数的方案数=总方案数-没有一个数是质数的方案数。
  • 所有数的和是p 的倍数:因为p的范围很小,可以在模p意义下考虑。

然后发现这是一个dp。

dp[i][j] 表示前 i 个数的和模 p 为 j 的方案数。

发现可以用矩阵快速幂优化。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=20000010,P=110,mod=20170408;
 4 int n,m,p,prime[N],tot,cnt[P],all[P];
 5 bool isp[N];
 6 void pre(){
 7     isp[1]=1,cnt[1%p]++,all[1%p]++;
 8     for(int i=2;i<=m;i++){
 9         all[i%p]++;
10         if(!isp[i]){prime[++tot]=i;}
11         else cnt[i%p]++;
12         for(int j=1;j<=tot&&1LL*prime[j]*i<=m;j++){
13             isp[i*prime[j]]=1;
14             if(!(i%prime[j])) break;
15         }
16     }
17     return;
18 }
19 struct Mat{
20     int n,m,num[P][P];
21     Mat(){
22         n=m=0;
23         memset(num,0,sizeof(num));
24         return;
25     }
26     void set1(){for(int i=1;i<=n;i++) num[i][i]=1;return;}
27     Mat operator*(const Mat& k)const{
28         Mat c;
29         c.n=n,c.m=k.m;
30         for(int i=0;i<n;i++)
31             for(int j=0;j<k.m;j++)
32                 for(int ii=0;ii<m;ii++)
33                     c.num[i][j]=((long long)c.num[i][j]+(long long)num[i][ii]*k.num[ii][j])%mod;
34         return c;
35     }
36     void print(){
37         for(int i=0;i<n;i++){
38             for(int j=0;j<m;j++) cout<<num[i][j]<<" ";
39             cout<<endl;
40         }
41         cout<<endl;
42         return;
43     }
44 };
45 void qpow(Mat x,int y,Mat& res){
46     res.n=x.n,res.m=x.m;
47     res.set1();
48     while(y){
49         if(y&1) res=res*x;
50         x=x*x,y>>=1;
51     }
52     return;
53 }
54 
55 int main(){
56     scanf("%d%d%d",&n,&m,&p);
57     pre();
58     Mat a,b,c,d;
59     a.n=a.m=b.n=b.m=p;
60     c.n=d.n=p,c.m=d.m=1;
61     for(int i=0;i<p;i++){
62         for(int j=0;j<p;j++) a.num[i][j]=cnt[(i-j+p)%p],b.num[i][j]=all[(i-j+p)%p];
63     }
64     c.num[0][0]=d.num[0][0]=1;
65     qpow(a,n-1,a);qpow(b,n-1,b);
66     c=a*c,d=b*d;
67     int ans=((d.num[0][0]-c.num[0][0])%mod+mod)%mod;
68     printf("%d",ans);
69     return 0;
70 }

 

posted @ 2018-03-16 11:15  Cupcake  阅读(123)  评论(0编辑  收藏  举报