[SDOI 2015] 序列计数

12人阅读 评论(0) 收藏 举报
分类:

题目描述:

雾.

题目分析:

首先写出朴素的DP方程
DP[i][j]ij
DP[i+1][(jk)%m]=kDP[i][j]C[k] C[S]为集合S是否存在K
这个DP为O(m2n)
看到 m 的特殊性 为一个质数
引入一个原根的概念

对于一个素数p,他的一个原根g的0~p-2次幂在模p意义下取遍1~p-1的所有值
求原根可以先找出p-1的所有质因数,然后从2开始枚举,如果对任意的p-1的质因数p[i],x的(p-1)/p[i]次幂模p都不等于1,则x是p的一个原根

原根一般比较小,可以暴力找

那么上面的DP方程就可以写成

DP[i+1][(j+k)%(M1)]=kDP[i][j]C[k] 很明显就是一个卷积的形式了
套用多项式快速幂即可得到答案
最后复杂度为O(lognmlogm)

另外本题的模数是符合NTT形式的.

题目链接:

BZOJ 3992
COGS 1981
Luogu 3321

Ac 代码:

// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define int long long
const int mod=1004535809,g=3,gi=334845270;
const int maxm=8000*100; 
inline int fastpow(int x,int y,int p=mod)
{
    int ans=1;
    for(;y;y>>=1,x=(x*x)%p)
     if(y&1) ans=(ans*x)%p;
    return ans%p;
}
int rev[maxm],bin[maxm];
inline void NTT(int *a,int n,int f)
{
    int len=bin[n];
    for(int i=0;i<n;i++) rev[i]=((rev[i>>1]>>1)|((i&1)<<(len-1)));
    for(int i=0;i<n;i++) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
    for(int i=1;i<n;i<<=1)
    {
        int wn=fastpow((f==1)?g:gi,(mod-1)/(i<<1));
        for(int j=0;j<n;j+=(i<<1))
        {
            int w=1;
            for(int k=0;k<i;k++,w=(wn*w)%mod)
            {
                int x=a[j+k],y=(w*a[i+j+k])%mod;
                a[j+k]=(x+y)%mod,a[i+j+k]=(x-y+mod)%mod;
            }
        }
    }
    if(f==-1)
    {
        int inv=fastpow(n,mod-2);
        for(int i=0;i<n;i++) a[i]=(a[i]*inv)%mod;
    }
}
int n,m,x,s,G,H[maxm],C[maxm],vis[maxm];//H为数对应的幂次,C为存在性 
int ans[maxm];
inline void init()
{
    for(int i=1;i<m;i++)
    {
        memset(vis,0,sizeof(vis));
        int flag=1;
        for(int j=1;j<m&&flag;j++)
        {
            int tmp=fastpow(i,j,m);
            if(vis[tmp]) flag=0;
            vis[tmp]=1;
        }
        if(flag)
        {
            G=i;
            break;
        }
    }
    //printf("%lld\n",G);
    for(int i=0;i<m;i++) H[fastpow(G,i,m)]=i;
    for(int i=0;i<18;i++) bin[1<<i]=i;
}
inline void getans(int *a,int n,int y)
{
    y--;
    for(int i=0;i<n;i++) ans[i]=a[i];
    while(y)
    {
        if(y&1)
        {
            NTT(ans,n,1),NTT(a,n,1);
            for(int i=0;i<n;i++) ans[i]=(ans[i]*a[i])%mod;
            NTT(a,n,-1),NTT(ans,n,-1);
            for(int i=m-1;i<n;i++) ans[i%(m-1)]=(ans[i%(m-1)]+ans[i])%mod,ans[i]=0;
        }
        NTT(a,n,1);
        for(int i=0;i<n;i++) a[i]=(a[i]*a[i])%mod;
        NTT(a,n,-1);
        for(int i=m-1;i<n;i++) a[i%(m-1)]=(a[i%(m-1)]+a[i])%mod,a[i]=0;
        y/=2;
    }
}
signed main()
{
    //freopen("sdoi2015_sequence.in","r",stdin);
    //freopen("sdoi2015_sequence.out","w",stdout);
    scanf("%lld%lld%lld%lld",&n,&m,&x,&s);
    init();

    for(int i=1;i<=s;i++)
    {
        int num;
        scanf("%lld",&num);
        if(num) C[H[num]%(m-1)]=1;
    }
    int Len;
    for(Len=1;Len<=2*m;Len<<=1);
    getans(C,Len,n);
    printf("%lld\n",ans[H[x]%(m-1)]);
    return 0;
}
查看评论

4818: [Sdoi2017]序列计数

4818: [Sdoi2017]序列计数Time Limit: 30 Sec Memory Limit: 128 MB Submit: 396 Solved: 267 [Submit][Sta...
  • CRZbulabula
  • CRZbulabula
  • 2017-04-15 18:06:01
  • 563

bzoj 4818: [Sdoi2017]序列计数 动态规划+矩阵乘法

题意Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数。 Alice还希望,这nn个数中,至少有一个数是质数。 Alice想知道,有多少个序列...
  • qq_33229466
  • qq_33229466
  • 2017-04-11 16:20:11
  • 1151

hdu4542 求反素数

题意Problem Description   “今有物不知其数,三三数之有二,五五数之有三,七七数之有二,问物几何?”  这个简单的谜题就是中国剩余定理的来历。  在艰难地弄懂了这个定理之后,小明...
  • hndu__lz
  • hndu__lz
  • 2016-04-01 00:33:19
  • 287

【 bzoj 3992 】 [SDOI2015]序列统计 - NTT 生成函数

看起来很厉害的题   然而想到原根的话这题就成sb题了   因为模M为质数,所以一定存在原根,所以[0,M−2][0,M-2]内可以建立与[1,M−1][1,M-1]一一对应的关系。通过原根就...
  • GEOTCBRL
  • GEOTCBRL
  • 2015-12-16 22:26:36
  • 746

bzoj4517 sdoi2016 排列计数 错排

题目大意:给定n,m。求排列个数,排列满足:1、是全排列的一种。2,、有且仅有m个数a[i] = i。 嗯,今天(第一次)听说了个错排这个东西。。诶。不过开心,smz妹子给我讲哒~ 错排就是求n的排列...
  • yxr0105
  • yxr0105
  • 2016-05-26 18:50:14
  • 322

【SDOI2017】序列计数

题目描述题目解析呵呵,实际这是NOIP题你信吗? 如果不考虑包含质数的情况,因为p很小,我们不妨构建p*p的矩阵,然后对于(i,j)填有多少个数x使得(i+x)%p=j,最后矩阵快速幂一下就行了。 ...
  • qq_35479641
  • qq_35479641
  • 2017-05-18 17:54:56
  • 227

BZOJ 4816 [Sdoi2017]数字表格

莫比乌斯反演题目就是要求,不妨设 n
  • ziqian2000
  • ziqian2000
  • 2017-04-17 22:27:29
  • 367

[Sdoi2017]序列计数

DescriptionAlice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列...
  • liu1318257253
  • liu1318257253
  • 2018-02-20 16:09:10
  • 51

[BZOJ4517][Sdoi2016]排列计数(错排+组合数)

即使翅膀折了,心也要飞翔。
  • Clove_unique
  • Clove_unique
  • 2016-05-02 23:09:34
  • 489

4821: [Sdoi2017]相关分析

4821: [Sdoi2017]相关分析Time Limit: 10 Sec Memory Limit: 128 MB Submit: 191 Solved: 29 [Submit][Stat...
  • CRZbulabula
  • CRZbulabula
  • 2017-04-15 18:39:35
  • 399
    个人资料
    持之以恒
    等级:
    访问量: 6万+
    积分: 7045
    排名: 4097
    文章分类
    最新评论