DTOJ # 3160. Sequence count (count)

Description [title]

Alice wants to get a positive integer of length n-$ $ sequence, the sequence is not more than $ m $, and this $ $ n-number and a multiple of $ p $.

Alice is also desirable, that $ $ n-number, at least a number is a prime number.

Alice wanted to know how many sequences satisfy her request.

[Input Format]

Row of three numbers, $ n, m, p $.

[Output format]

A sequence number of a line number, Alice meet the requirements. Since many possible sequences satisfy the conditions, the output of the modulo $ $ 20,170,408.

[Sample]

Sample input
353

sample output
33

[Note] with the data range

For $ 20 \% $ data, $ 1 \ le n \ le 100,1 \ le m \ le 100 $.

For $ 50 \% $ data, $ 1 \ le m \ le 100 $.

For $ 80 \% $ data, $ 1 \ le m \ le 10 ^ 6 $.

For $ 100 \% $ data, $ 1 \ le n \ le 10 ^ 9,1 \ le m \ le 2 \ times 10 ^ 7,1 \ le p \ le 100 $.

【answer】

Provided $ f [i] [j] [0/1] $ $ I $ denotes the number of the front, and at $ mod \ p $ $ J $ meaning, if taking the number of prime numbers embodiment.

After the transfer list with a quick power or polynomial matrix can be optimized.

[Code]

#include<bits/stdc++.h>
const int mod=20170408;
int n,m,p,pr[20000010],tot;
bool flag[20000010];
struct Poly
{
    int a[110];
    inline friend Poly operator + ( const Poly &p1,const Poly &p2 )
    {
        Poly p3;memset(p3.a,0,sizeof(p3.a));
        for ( int i=0;i<p;i++ ) p3.a[i]=(p1.a[i]+p2.a[i])%mod;
        return p3;
    }
    inline friend Poly operator - ( const Poly &p1,const Poly &p2 )
    {
        Poly p3;memset(p3.a,0,sizeof(p3.a));
        for ( int i=0;i<p;i++ ) p3.a[i]=(p1.a[i]-p2.a[i]+mod)%mod;
        return p3;
    }
    inline friend Poly operator * ( const Poly &p1,const Poly &p2 )
    {
        Poly p3;memset(p3.a,0,sizeof(p3.a));
        for ( int i=0;i<p;i++ ) for ( int j=0;j<p;j++ ) p3.a[(i+j)%p]=(p3.a[(i+j)%p]+1LL*p1.a[i]*p2.a[j])%mod;
        return p3;
    }
    inline friend Poly operator ^ ( Poly p,int n )
    {
        Poly res;memset(res.a,0,sizeof(res.a));res.a[0]=1;
        for ( ;n;n>>=1,p=p*p ) if ( n&1 ) res=res*p;
        return res;
    }
}A,B;
signed main()
{
    scanf("%d%d%d",&n,&m,&p);
    flag[1]=true;
    for ( int i=2;i<=m;i++ )
    {
        if ( !flag[i] ) pr[++tot]=i;
        for ( int j=1;j<=tot and pr[j]*i<=m;j++ )
        {
            flag[i*pr[j]]=true;
            if ( !(j%i) ) break;
        }
    }
    for ( int i=1;i<=m;i++ ) A.a[i%p]++,B.a[i%p]+=flag[i];
    for ( int i=0;i<p;i++ ) A.a[i]%=mod,B.a[i]%=mod;
    printf("%d\n",((A^n)-(B^n)).a[0]);
}

 

Guess you like

Origin www.cnblogs.com/RenSheYu/p/11327244.html