1. 程式人生 > >2018.12.31 bzoj3992: [SDOI2015]序列統計(生成函式+ntt+快速冪)

2018.12.31 bzoj3992: [SDOI2015]序列統計(生成函式+ntt+快速冪)

傳送門
生成函式簡單題。
題意:給出一個集合 A = { a 1 , a 2

, . . . a s } A=\{a_1,a_2,...a_s\}
,所有數都在 [ 0 , m 1 ] [0,m-1] 之間, m m 是一個質數,求滿足全部由這個集合裡的組成且長度為 n n 且所有數之積與 x x 在模 m m 意義下相同的數列總數。


思路:對 a 1 , a 2 , . . , a s , x a_1,a_2,..,a_s,x 全部化成 g b 1 , g b 2 , . . . g b s , g y g^{b_1},g^{b_2},...g^{b_s},g^{y} ,然後就轉乘法為加法。
於是只用求 x 1 + x 2 + . . . + x n y m o d    m 1 x_1+x_2+...+x_n\equiv y\mod m-1 ,其中 x i { b 1 , b 2 , . . . b s } x_i\in\{b_1,b_2,...b_s\} 的方案數。
對於 x i x_i 可以構造出生成函式 1 + x b 1 + x b 2 + . . . + x b s 1+x^{b_1}+x^{b_2}+...+x^{b_s} ,於是答案的生成函式就是 ( 1 + x b 1 + x b 2 + . . . + x b s ) n (1+x^{b_1}+x^{b_2}+...+x^{b_s})^n ,考慮到 n n 很大可以用快速冪+ n t t ntt 解決。
注意特判 a i = 0 a_i=0 的情況以及每次 n t t ntt 完了之後要重新把多項式的最高次數控制為 m 2 m-2
程式碼:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=3e6+5,mod=1004535809;
int M,lim=1,tim=0,pos[N],a[N],P,n,x,idx[N];
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline int mul(int a,int b){return (ll)a*b%mod;}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;}
inline void ntt(int a[],int type){
	for(ri i=0;i<lim;++i)if(i<pos[i])swap(a[i],a[pos[i]]);
	for(ri wn,mult=(mod-1)>>1,typ=type==1?3:334845270,mid=1;mid<lim;mid<<=1,mult>>=1){
		wn=ksm(typ,mult);
		for(ri j=0,len=mid<<1;j<lim;j+=len)for(ri w=1,k=0,a0,a1;k<mid;++k,w=mul(w,wn)){
			a0=a[j+k],a1=mul(w,a[j+k+mid]);
			a[j+k]=add(a0,a1),a[j+k+mid]=dec(a0,a1);
		}
	}
	if(type==-1)for(ri inv=ksm(lim,mod-2),i=0;i<lim;++i)a[i]=mul(a[i],inv);
}
inline void poly_mul(int a[],int b[]){
	static int A[N],B[N];
	for(ri i=0;i<lim;++i)A[i]=a[i],B[i]=b[i];
	ntt(A,1),ntt(B,1);
	for(ri i=0;i<lim;++i)A[i]=mul(A[i],B[i]);
	ntt(A,-1);
	for(ri i=0;i<lim;++i)a[i]=A[i];
	for(ri i=lim-1;i>=M-1;--i)a[i-M+1]=add(a[i-M+1],a[i]),a[i]=0;
}
inline void solve(int a[],int p){
	static int ret[N];
	memset(ret,0,sizeof(ret)),ret[0]=1;
	for(;p;p>>=1,poly_mul(a,a))if(p&1)poly_mul(ret,a);
	cout<<ret[x];
}
inline bool check(int g
            
           

相關推薦

2018.12.31 bzoj3992: [SDOI2015]序列統計生成函式+ntt+快速

傳送門 生成函式簡單題。 題意:給出一個集合 A = {

[BZOJ3992][SDOI2015]序列統計(DP+原根+NTT)

mod set sub mes bzoj 轉移 font \n sca 3992: [SDOI2015]序列統計 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1888 Solved: 898[Submit][Sta

BZOJ3992序列統計動態規劃,NTT

swap int 乘法 true ble spa main 們的 oid 【BZOJ3992】序列統計(動態規劃,NTT) 題面 BZOJ 題解 最裸的暴力 設\(f[i][j]\)表示前\(i\)個數,積在膜意義下是\(j\)的方案數 轉移的話,每次枚舉一個數,直接丟進去

BZOJ3992: [SDOI2015]序列統計

++ src ons close pla std lose == con https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有a*bΞx(mod m),則ord(a)+ord(b)Ξord(x)(mod

BZOJ3992: [SDOI2015]序列統計(NTT 原根 生成函數)

static sina har sts 原根 bre printf 個數 bzoj3 題意 題目鏈接 給出大小為\(S\)的集合,從中選出\(N\)個數,滿足他們的乘積\(\% M = X\)的方案數 Sol 神仙題Orz 首先不難列出最裸的dp方程,設\(f[i][j]\

[bzoj3992][SDOI2015]序列統計——離散對數+NTT

ons name make ret bre har 復雜度 etc 題目 題目大意: 給定一個數字不超過\(m\)的集合\(S\),用\(S\)中的數生成一個長度為\(n\)的序列,求所有序列中的元素乘積模\(m\)等於\(x\)的序列的個數。 思路: 考慮最樸素的\(DP

2018.09.26 bzoj5221: [Lydsy2017省隊十連測]偏題數學推導+矩陣快速

傳送門 由於沒有考慮n<=1的情況T了很久啊。 這題很有意思啊。 考試的時候根本不會,騙了30分走人。 實際上變一個形就可以了。 推導過程有點繁雜。 直接粘題解上的請諒解。 不得不說

BZOJ5298 CQOI2018交錯序列動態規劃+矩陣快速

  顯然答案為Σkb·(n-k)a·C(n-k+1,k)。並且可以發現ΣC(n-k,k)=fibn。但這實際上沒有任何卵用。   純組合看起來不太行得通,換個思路,考慮一個顯然的dp,即設f[i][j][0/1]為前i為選了j個1其中第i位是0/1的方案數。這樣當然能求出答案,複雜度O(n2)。   注意

POJ 2778 DNA SequenceAC自動機+矩陣快速

ace str etc cto .org empty pan dac http http://poj.org/problem?id=2778 題意:給出一些病毒字符串,只由A,T,C,G組成,現在要用著4個字符組成長度為n的字符串,且字符串中不可以包含任一病毒字符串,問共

2016 pku campusH/OpenJ_POJ - C16H推公式+矩陣快速

pow exist ref amp nbsp 多少 ica contain lines 傳送門:http://poj.openjudge.cn/practice/C16H?lang=en_US   題面:描述 Wenwen has a magical ball. Whe

HDU6185 Covering 遞推+矩陣快速

esp over () n-1 告訴 matrix \n nbsp 答案 大致題意:讓你用1*2規格的地毯去鋪4*n規格的地面,告訴你n,問有多少種不同的方案使得地面恰好被鋪滿且地毯不重疊。答案對1000000007取模 遞推得f(n)=f(n-1)+5*f(n-2)+

【HDOJ5950】Recursive sequence矩陣乘法,快速

重點 模板 || getchar() 矩陣 col space pair color 題意:f[1]=a,f[2]=b,f[i]=2f[i-2]+f[i-1]+i^4(i>=3),多組詢問求f[n]對2147493647取模 N,a,b < 2^31 思路:重點

BZOJ4887 Tjoi2017可樂動態規劃+矩陣快速

  設f[i][j]為第i天到達j號城市的方案數,轉移顯然,答案即為每天在每個點的方案數之和。矩乘一發即可。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #

【計蒜客】2018ICPC焦作賽區網路賽G Give Candies小費馬定理+快速

題目連結 【題意】 有n個小朋友,排隊從老師手中領取n個糖,先到的小朋友先得到若干個糖,直到糖分完,輸出有幾種分配方式。 【解題思路】 規律很好找,就是(2^n-1)%p,但是n太大了,需要用費馬小定理轉換一下。 費馬小定理:若gcd(a,p)=1,那麼

POJ 2778AC自動機+矩陣快速

        非常有趣的一道題,題目給m個病毒串,問不包含病毒串的長度n的DNA片段有幾個。         用病毒串構造AC自動機,用fail指標跑出字串狀態間的到達關係和危險點,危險點即到達即代表某串含有病毒的點。         用AC自動機構造出矩陣,初始矩陣中

第二次講課內容函式快速

函式 在c語言中 main() 就是一個函式,它是程式的主函式。 函式定義的一般格式: 返回型別 函式名(引數列表){ 函式體 } 返回型別 一個函式可以返回一個值,返回型別就是對應的值的型別。常見的有int、long long、bool、double、flo

HDU 4704 Sum 費馬定理+快速

Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Subm

Luogu5162 WD與積木生成函式+多項式求逆

  顯然的做法是求出斯特林數,但沒有什麼優化空間。   考慮一種暴力dp,即設f[i]為i塊積木的所有方案層數之和,g[i]為i塊積木的方案數。轉移時列舉第一層是哪些積木,於是有f[i]=g[i]+ΣC(i,j)·f[i-j],g[i]=ΣC(i,j)·g[i-j] (j=1~i)。   考慮優化 。我們

2019.01.03 bzoj3456: 城市規劃生成函式+多項式取對

傳送門 生成函式好題。 題意:求n個點的簡單(無重邊無自環)無向連通圖數目 思路: 對簡單無向圖構造生成函式 f (

LOJ2325「清華集訓 2017」小Y和恐怖的奴隸主期望概率+矩陣快速

LOJ2325「清華集訓 2017」小Y和恐怖的奴隸主 題意: "A fight? Count me in!" 要打架了,算我一個。 "Everyone, get in here!" 所有人,都過來! 小Y是一個喜歡玩遊戲的OIer。一天,她正在