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[1], 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[102],y[102],ans[102],by[102];
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]=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[0]=1;
    for(;x;x>>=1,cheng(a,a))
    if(x&1)
    cheng(ans,a);
    return ans[0];
}

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