# BZOJ4818: Sequence Count (doubling + dp)

I saw the convolution at a glance, and it intrigued me so much that I realized it was just like this.

Face
Topic: Ask n, 1~m for each number, at least one prime number, and how many sequences are multiples of p, modulus 1e9+7.N < 1e9, m < 2e7, P < 100.

Seeing "there is at least one prime number", which is probably something like repulsion, subtracts the problem from (the result of 1~m) (the result of sum and 1).

Set f[i][j] as the number of schemes with length I and module P as J.g=f, enumerate the remainder of the next module p, and you can transfer.

f[i][j]=k=0p f[i_1][k]g[(j_k+p) module p]

Perhaps you can double it. You can do it without crt+ntt.

```#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))

typedef long long LL;

const int N=20020000,nn=2e7;
const LL mo=20170408;

int n,m,p;
int prime[N],num;
LL x,y,ans,by;
bool b[N];

void pre()
{
for(int i=2;i<=nn;i++)
{
if(!b[i])
prime[++num]=i;
for(int j=1;j<=num&&i*prime[j]<=nn;j++)
{
b[prime[j]*i]=1;
if(i%prime[j]==0)
break;
}
}
b=1;
}

void cheng(LL *a,LL *b)
{
mmst(by,0);
for(int i=0;i<p;i++)
for(int j=0;j<p;j++)
by[(i+j)%p]=(by[(i+j)%p]+a[i]*b[j])%mo;
mmcp(a,by);
}

LL work(LL *a,int x)
{
mmst(ans,0);
ans=1;
for(;x;x>>=1,cheng(a,a))
if(x&1)
cheng(ans,a);
return ans;
}

int main()
{
pre();
cin>>n>>m>>p;
for(int i=1;i<=m;i++)
{
x[i%p]++;
if(b[i])
y[i%p]++;
}

cout<<(work(x,n)-work(y,n)+mo)%mo<<endl;

return 0;
}
``` This is the water theme specialty of yarn fog.

Posted on Sun, 05 Jul 2020 10:39:59 -0400 by ubuntu-user