UVA 12298 Super Poker II
来源:互联网 发布:java http 幂等 编辑:程序博客网 时间:2024/06/08 15:52
转载请注明出处,谢谢http://blog.csdn.net/bigtiao097?viewmode=contents
题意:
给定一些扑克牌,value为合数,其中丢了c张牌,问这些扑克牌选四色(必须一个花色选一张)能组成n的方案数
思路:
素筛,然后构造四个多项式(每个花色一个),去掉丢失的牌
将这四个多项式相乘,利用FFT,得到的就是方案数了
注意:精度会爆double,要用long double
最后结果会爆int,要用long long
输出不能用%I64d,要用%lld
Result: Accepted Time: 170ms
具体代码如下:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const long double PI = acos(-1);const int maxn = 5e4+5;//maxn = max(len1,len2)const int maxm = 4*maxn;//k是>=maxn的最小的2的幂,maxm=2*kint len1,len2,len;//len1,len2分别为两个多项式的最高次数+1ll S[maxn],H[maxn],C[maxn],D[maxn];char str[20];ll num1[maxm],num2[maxm];ll ans[maxm];bool vis[maxn];int a,b,c,x,y;void sieve(){ int m = sqrt(maxn+0.5); memset(vis, 0, sizeof vis); for(int i = 2; i <= m; i++) if(!vis[i]) for(int j = i*i; j < maxn; j+=i) vis[j] = 1;}//复数结构体struct Complex{ long double x, y;//实部为x,虚部为y Complex(long double x=0,long double y=0):x(x),y(y){} Complex operator+(const Complex &rhs) const { return Complex(x+rhs.x, y+rhs.y);} Complex operator-(const Complex &rhs) const { return Complex(x-rhs.x, y-rhs.y);} Complex operator*(const Complex &rhs) const { return Complex(x*rhs.x-y*rhs.y,x*rhs.y+y*rhs.x);}};Complex x1[maxm],x2[maxm];/*进行FFT和IFFT前的反转变换。将位置i和(i二进制反转后位置)互换。len必须取2的幂*/void change(Complex *x, int len){ Complex t; for(int i = 1, j = len/2; i < len-1; i++) { //交换下标互反的元素,i<j保证交换一次 //i做正常的+1,j做反转的+1,始终保持i和j是反转的 if(i < j) { t = x[i]; x[i] = x[j]; x[j] = t; } int k = len / 2; while(j >= k) { j -= k; k >>= 1; } if(j < k) j += k; }}/*做FFTlen必须为2的幂on==1时是DFT,on==-1时是IDFT*/void fft(Complex *x, int len, int on){ change(x, len); for(int h = 2; h <= len; h <<= 1) { Complex wn(cos(-on*2*PI/h), sin(-on*2*PI/h)); for(int j = 0; j < len; j += h) { Complex w(1, 0); for(int k = j; k < j+h/2; k++) { Complex u = x[k]; Complex t = w*x[k+h/2]; x[k] = u+t; x[k+h/2] = u-t; w = w*wn; } } } if(on == -1) for(int i = 0; i < len; i++) x[i].x /= len;}void workFFT(ll *xx,int len1,ll *yy,int len2,ll *num){ len = 1; memset(x1,0,sizeof x1); memset(x2,0,sizeof x2); memset(num,0,sizeof num); while(len < len1*2 || len < len2*2) len <<=1; for(int i = 0; i < len; i++) x1[i] = x2[i] = Complex(0,0); for(int i = 0; i < len1; i++) x1[i] = Complex(xx[i],0); for(int i = 0; i < len2; i++) x2[i] = Complex(yy[i],0); fft(x1,len,1); fft(x2,len,1); for(int i = 0; i < len; i++) x1[i] = x1[i]*x2[i]; fft(x1,len,-1); for(int i = 0; i < len; i++) num[i] = (ll)(x1[i].x+0.5);}int main(){ sieve(); while(~scanf("%d%d%d",&a,&b,&c),a+b+c) { for(int i=2;i<=b;i++) if(vis[i]) { //cout<<i<<endl; S[i]=1; H[i]=1; C[i]=1; D[i]=1; } for(int i=1;i<=c;i++) { scanf("%s",str); x = strlen(str); y = str[0]-'0'; for(int i=1;i<x-1;i++) y = y*10 + str[i]-'0'; if(str[x-1]=='H') H[y]=0; if(str[x-1]=='S') S[y]=0; if(str[x-1]=='C') C[y]=0; if(str[x-1]=='D') D[y]=0; } workFFT(H,b+1,S,b+1,num1); workFFT(C,b+1,D,b+1,num2); workFFT(num1,b+1,num2,b+1,ans); for(int i=a;i<=b;i++) printf("%lld\n",ans[i]); printf("\n"); }}
阅读全文
0 0
- UVA 12298 Super Poker II
- UVA 12298 Super Poker II
- UVA 12298 Super Poker II(FFT)
- UVA 12298——Super Poker II
- [UVA 12298 Super Poker II]FFT/NTT
- UVA 12298 Super Poker II(FFT)
- UVA 12298 Super Poker II (FFT + long double)
- UVA12298 Super Poker II 递推
- uva12298(Super Poker II)-FFT(快速傅里叶变换)
- UVA 12297 Super Poker(矩阵快速幂)
- UVa 10315 - Poker Hands
- UVA 10315 - Poker Hands
- UVA 10315 - Poker Hands
- uva 10315 Poker Hands
- UVa 10315 Poker Hands
- UVa 10315 - Poker Hands
- UVA Poker Hands题解
- UVa 12585 Poker End Games
- 让div或img在div中垂直居中
- HDU-3727 Jewel(查询第K大是几,以及数字是第几大)
- 初识PHP
- Maven Install
- jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
- UVA 12298 Super Poker II
- 摘抄Hog原论文中重要观点【Histograms of Oriented Gradients for Human Detection】
- 旋转加登录界面
- abp后台分页,排序引用dll说明
- Cesium学习笔记(九):导入3D模型(obj转gltf)
- EventBus 3.0
- 数据库实体间有三种对应关系:一对一,一对多,多对多。
- 基于AOP/TX来实现事务操作
- android drawable-hdpi xhdpi xxhdpi xxxhdpi 的理解