zoukankan      html  css  js  c++  java
  • bzoj 3992: [SDOI2015]序列统计

    膝盖++,IQ--

    SD总是酱紫。。。。。吐槽+++++++

    这个乘积的形式是可以用他的原根表示成加法的!!神奇啊!!!

    然后加法就很棒棒了,我们可以用生成函数这个东西来计算一下了。

    然后NTT就好了!!

    还有这里有一个像快速幂的东西,而且把大于模数的东西搞小,是循环卷积的形式吗??好神奇啊

    原根真的是劲啊

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cmath>
     4 #define LL long long
     5 #define pi acos(-1)
     6 using namespace std;
     7 
     8 const int mod=(479<<21)+1,G=3,maxn=17000;
     9 
    10 int n,k,sum,m,inv_G,inv_N,T[maxn],vis[maxn],ind,N,rev[maxn],pos[maxn],root;  
    11 
    12 int ksm(int x, int p)
    13 {
    14     int sum=1;
    15     for (;p;p>>=1,x=(LL)x*x%mod)
    16         if (p&1) sum=(LL)sum*x%mod;
    17     return sum;
    18 }
    19 
    20 int rever(int x) {int res=0,len=N; while (len--) res<<=1,res^=(x&1),x>>=1; return res;}
    21 
    22 bool check(int x)
    23 {
    24     int now=1; ++ind;
    25     for (int i=1; i<n; i++,now=now*x%n){
    26         if (vis[now]==ind) return 0;
    27         vis[now]=ind;
    28     }
    29     return 1;
    30 }
    31 int find_root() {for (int i=2; i<=n; i++) if (check(i)) return i;}
    32 
    33 struct Orz
    34 {
    35     int a[maxn];
    36     void NTT(int opt)
    37     {
    38         for (int i=0; i<N; i++) if (rev[i]>i) swap(a[rev[i]],a[i]);
    39         int g=opt==1?G:inv_G;
    40         for (int h=2; h<=N; h<<=1)
    41         {
    42             int t=ksm(g,(mod-1)/h);
    43             for (int i=0; i<N; i+=h)
    44                 for (int j=0,w=1; j<(h>>1); j++,w=(LL)w*t%mod)
    45                 {
    46                     int x=a[i+j],y=(LL)a[i+j+(h>>1)]*w%mod;
    47                     a[i+j]=(x+y)%mod; a[i+j+(h>>1)]=(x-y+mod)%mod;
    48                 }
    49         }
    50         if (opt==-1) for (int i=0; i<N; i++) a[i]=(LL)a[i]*inv_N%mod;
    51     }
    52 }a,b;
    53 
    54 void quick_pow()
    55 {
    56     b.a[0]=1;
    57     for (;k;k>>=1)
    58     {
    59         a.NTT(1);
    60         if (k&1)
    61         {
    62             b.NTT(1); for (int i=0; i<N; i++) b.a[i]=(LL)b.a[i]*a.a[i]%mod;
    63             b.NTT(-1); for (int i=N-1; i>=n-1; i--) b.a[i-n+1]=(b.a[i-n+1]+b.a[i])%mod,b.a[i]=0;  //循环卷积????
    64         }
    65         for (int i=0; i<N; i++) a.a[i]=(LL)a.a[i]*a.a[i]%mod; a.NTT(-1);
    66         for (int i=N-1; i>=n-1; i--) a.a[i-n+1]=(a.a[i-n+1]+a.a[i])%mod,a.a[i]=0;
    67     }
    68 }
    69 
    70 int main(int argc, char const *argv[])
    71 {
    72     inv_G=ksm(G,mod-2);
    73     scanf("%d%d%d%d",&k,&n,&sum,&m);
    74     for (int i=1; i<=m; i++) scanf("%d",&T[i]);
    75     N=(int)ceil(log2(n))+1;
    76     for (int i=0; i<(1<<N); i++) rev[i]=rever(i);
    77     N=1<<N; inv_N=ksm(N,mod-2); root=find_root();
    78     for (int i=0,res=1; i<n-1; i++) pos[res]=i,res=res*root%n;
    79 
    80     for (int i=1; i<=m; i++) if (T[i]) a.a[pos[T[i]]]++;
    81     quick_pow();
    82     printf("%d
    ",b.a[pos[sum]]);
    83     return 0;
    84 }
  • 相关阅读:
    MyBatis入门案例
    springboot mybatis 后台框架平台 集成代码生成器 shiro 权限
    原谅这世界没那么美好
    十万的License只取决于一个连接
    Qt连接数据库的两种方法
    桃李春风一杯酒 江湖夜雨十年灯
    ERROR:Can't connect to local MySQL server through socket可能出现的情况
    MySQL忽略授权表方式<--skip-grant-tables>重置管理用户密码
    MySQL5.7和5.6初始化数据的区别
    Rsync同步过程中遇到的常见问题
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6737110.html
Copyright © 2011-2022 走看看