zoukankan      html  css  js  c++  java
  • 【题解】P3747 [六省联考2017]期末考试 (单位根反演)

    【题解】P3747 [六省联考2017]组合数问题(单位根反演)

    就是要我们求

    [sum_{i=0}^k {nkchoose ik+r} ]

    换一个形式

    [=sum_{i=0}^{nk} {nkchoose i} [k|i-r] ]

    单位根反演带入

    [={1over k}sum_{i=0}^{nk} {nkchoose i} sum _{j=0}^{k-1} omega_k^{(i-r)j} ]

    凑一个二项式

    [={1over k}sum_{i=0}^{nk} sum_{j=0}^{k-1} {nkchoose i} omega_k^{ij}cdot omega_k^{-rj} ]

    交换和式

    [={1over k}sum_{j=0}^{k-1} omega_k^{-jr} sum_{i=0}^{nk} {nkchoose i} omega_k^{ij} ]

    也就是

    [{1over k}sum_{j=0}^{k-1} omega_k^{-jr} (1+omega_k^j)^{nk} ]

    (这个形式是一个FFT的形式),令(f(x)=(1+x)^{nk}),原式即

    [{1over k} sum_{j=0}^{k-1} omega_k^{-jr} f(omega_k^j) ]

    考虑范德蒙德的逆矩阵,即

    [V_k^{-1}={1 over k}egin{pmatrix} {1}&{1}&{cdots}&{1}\ {1}&{omega_k^{-1}}&{cdots}&{omega_k^{-(k-1)}}\ {1}&{omega_k^{-2}}&{cdots}&{omega_k^{-(k-1)2}}\ {vdots}&{vdots}&{}&{vdots}\ {1}&{omega_k^{-(k-1)}}&{cdots}&{omega_k^{-(k-1)(k-1)}}\ end{pmatrix} ]

    (f(omega_k^j))是一个点值,而({1over k} sum_{j=0}^{k-1} omega_k^{-jr} f(omega_k^j)),就是:由点值构成的行向量([f(omega_k^0) quad f(omega_k^1)dots f(omega_k^{k-1})] imes V_{k}^{-1})的第(r)列的值!也就是(f(x))这个多项式循环卷积(因为我们带入的都是(k)次单位根,于是(f(x) mod x^k-1)意义下的)意义下第(r)项的值。(根据dft和idft的定义)

    然后这里(k)很小,直接暴力卷积即可

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    
    using namespace std;  typedef long long ll;
    typedef vector<int> poly;
    int n,mod,k,r;
    int MOD(const int&x){return x>=mod?x-mod:x;}
    int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
    poly operator * (poly a,poly b){
    	if(a.empty()||b.empty()) return poly(k,0);
    	poly ret(k);
    	for(int t=0,ed=a.size();t<ed;++t)
    		for(int i=0,ed=b.size();i<ed;++i)
    			ret[(t+i)%k]=MOD(ret[(t+i)%k]+MOD(a[t],b[i]));
    	return ret;
    }
    poly ksm(ll x){
    	poly ret(k,0),b(k,0);
    	ret[0]=1; ++b[0]; ++b[1%k];
    	while(x){
    		if(x&1) ret=ret*b;
    		b=b*b,x>>=1;
    	}
    	return ret;
    }
    int main(){
    	cin>>n>>mod>>k>>r;
    	cout<<ksm(1ll*n*k)[r]<<endl;
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    QOMO Linux 4.0 正式版发布
    LinkChecker 8.1 发布,网页链接检查
    pgBadger 2.1 发布,PG 日志分析
    Aletheia 0.1.1 发布,HTTP 调试工具
    Teiid 8.2 Beta1 发布,数据虚拟化系统
    zLogFabric 2.2 发布,集中式日志存储系统
    开源电子工作套件 Arduino Start Kit 登场
    Piwik 1.9 发布,网站访问统计系统
    Ruby 1.9.3p286 发布,安全修复版本
    toBraille 1.1.2 发布,Java 盲文库
  • 原文地址:https://www.cnblogs.com/winlere/p/12739234.html
Copyright © 2011-2022 走看看