日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

#3771. Triple 生成函数 + FFT + 容斥

發(fā)布時(shí)間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 #3771. Triple 生成函数 + FFT + 容斥 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

傳送門

文章目錄

  • 題意:
  • 思路:

題意:

思路:

注意到這個(gè)題是求若干個(gè)數(shù)的組合數(shù),(a,b),(b,a)(a,b),(b,a)(a,b),(b,a)視為一種方案,所以我們考慮生成一個(gè)普通型生成函數(shù)。
考慮到每個(gè)數(shù)只能選一次,但是如果我們生成函數(shù)相乘的話是不能控制每個(gè)數(shù)選多少次的,可以簡單腦補(bǔ)一下兩個(gè)循環(huán)相乘,得到的結(jié)果。由于選的物品最多有三個(gè),所以我們考慮分開討論。
我們構(gòu)造函數(shù)a(x)a(x)a(x)表示每個(gè)物品選一次,b(x)b(x)b(x)表示每個(gè)物品選兩次,c(x)c(x)c(x)表示每個(gè)物品選三次。
(1)(1)(1)對于只選一個(gè)物品,答案直接為a(x)a(x)a(x)即可。
(2)(2)(2)對于選了兩個(gè)物品的情況,我們?nèi)绻苯佑?jì)算a2(x)a^2(x)a2(x)的話會發(fā)現(xiàn)有重復(fù)的部分,這個(gè)重復(fù)的部分就是每個(gè)數(shù)選了兩次,所以要減去b(x)b(x)b(x),由于其組合有222種,答案即為a2(x)?b(x)2\frac{a^2(x)-b(x)}{2}2a2(x)?b(x)?
(3)(3)(3)對于選了三個(gè)物品的情況,直接計(jì)算a3(x)a^3(x)a3(x)也是有很多重復(fù)的,考慮從三個(gè)中選兩個(gè)相同的位置,這個(gè)時(shí)候方案數(shù)即為(32)?a(x)?b(x)\binom{3}{2}*a(x)*b(x)(23?)?a(x)?b(x),再考慮從三個(gè)中選三個(gè)相同的位置,由于剛才已經(jīng)減去了333倍的了,所以需要加上2?c(x)2*c(x)2?c(x)。由于各自的組合有666種,所以最終答案為a3(x)?3?a(x)?b(x)+2?c(x)6\frac{a^3(x)-3*a(x)*b(x)+2*c(x)}{6}6a3(x)?3?a(x)?b(x)+2?c(x)?
直接FFTFFTFFT卷一下求答案即可。

//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #include<random> #include<cassert> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid ((tr[u].l+tr[u].r)>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=10000010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6,PI=acos(-1);int n,m; int A[N],B[N],C[N]; int rev[N]; int bit,limit;struct Complex {double x,y;Complex operator + (const Complex& t) const { return {x+t.x,y+t.y}; }Complex operator - (const Complex& t) const { return {x-t.x,y-t.y}; }Complex operator * (const Complex& t) const { return {x*t.x-y*t.y,x*t.y+y*t.x}; } }a[N],b[N],c[N],ans[N];void fft(Complex a[],int inv) {for(int i=0;i<limit;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);for(int mid=1;mid<limit;mid<<=1) {Complex w1=Complex({cos(PI/mid),inv*sin(PI/mid)});for(int i=0;i<limit;i+=mid*2) {Complex wk=Complex({1,0});for(int j=0;j<mid;j++,wk=wk*w1) {Complex x=a[i+j],y=wk*a[i+j+mid];a[i+j]=x+y; a[i+j+mid]=x-y;}}} }int main() { // ios::sync_with_stdio(false); // cin.tie(0);cin>>n;int mx=0;for(int i=1;i<=n;i++) {int x; scanf("%d",&x);a[x].x++; b[x*2].x++; c[x*3].x++;mx=max(mx,x*3);}while((1<<bit)<=mx) bit++;limit=1<<bit;for(int i=0;i<limit;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));fft(a,1); fft(b,1); fft(c,1);for(int i=0;i<limit;i++) {Complex x={3,0},y={2,0},z={1.0/6,0},h={1.0/2,0};ans[i]=ans[i]+(a[i]*a[i]*a[i]-x*a[i]*b[i]+y*c[i])*z;ans[i]=ans[i]+(a[i]*a[i]-b[i])*h;ans[i]=ans[i]+a[i];}fft(ans,-1);for(int i=0;i<limit;i++) {int val=(int)(ans[i].x/limit+0.5);if(val) printf("%d %d\n",i,val);}return 0; }

總結(jié)

以上是生活随笔為你收集整理的#3771. Triple 生成函数 + FFT + 容斥的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。