UVA 12298——Super Poker II

雨点打透心脏的1/2处 2022-07-19 11:56 157阅读 0赞

题意:

给定一些扑克牌,问这些扑克牌选四色能组成n的方案数,其中遗失了c张牌,这c张不能用,问n从a到b的方案数。

思路:

分析每一种花色,那么每种花色组成的方案数即为x^1+x^2+x^3+x^5(改花色的牌只有1,2,3,5这四张的时候),那么对比于其他的花色,也是一样,四个花色的方案数相乘,即为所得值,那么很容易来使用FFT,注意可能会超精度,复数要用long double。

code:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. using namespace std;
  7. const long double PI=acos(-1.0);
  8. typedef long double ld;
  9. struct complex
  10. {
  11. long double l,r;
  12. complex(ld ll=0.0,ld rr=0.0){
  13. l=ll;r=rr;
  14. }
  15. complex operator +(const complex& B){
  16. return complex(l+B.l,r+B.r);
  17. }
  18. complex operator - (const complex& B){
  19. return complex(l-B.l,r-B.r);
  20. }
  21. complex operator *(const complex& B){
  22. return complex(l*B.l-r*B.r,l*B.r+B.l*r);
  23. }
  24. };
  25. /* * 进行FFT和IFFT前的反转变换。 * 位置i和j(i二进制反转后位置)互换 * len必须是2的幂 */
  26. void change(complex y[],int len){
  27. int i,j,k;
  28. for (int i=1,j=len/2;i<len-1;i++){
  29. if (i<j) swap(y[i],y[j]);
  30. k=len/2;
  31. while (j>=k){
  32. j-=k;
  33. k>>=1;
  34. }
  35. if (j<k) j+=k;
  36. }
  37. }
  38. /* * 做FFT * len必须为2^k形式, * on==1时是DFT,on==-1时是IDFT */
  39. void fft(complex y[],int len,int on){
  40. change(y,len);
  41. for (int h=2;h<=len;h<<=1){
  42. complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
  43. for (int j=0;j<len;j+=h){
  44. complex w(1,0);
  45. for (int k=j;k<j+h/2;k++){
  46. complex u=y[k];
  47. complex t=w*y[k+h/2];
  48. y[k]=u+t;
  49. y[k+h/2]=u-t;
  50. w=w*wn;
  51. }
  52. }
  53. }
  54. if (on==-1){
  55. for (int i=0;i<len;i++){
  56. y[i].l/=len;
  57. }
  58. }
  59. }
  60. const int N=262144;
  61. const int M=50005;
  62. complex s[N],c[N],d[N],h[N];
  63. int vis[M],pri[M],tot;
  64. void getP(int n){
  65. memset(vis,0,sizeof(vis));
  66. tot=0;//vis[0]=vis[1]=1;
  67. for (int i=2;i<n;i++){
  68. if (!vis[i]) pri[tot++]=i;
  69. for (int j=0;j<tot&&i*pri[j]<n;j++){
  70. vis[i*pri[j]]=1;
  71. if (i%pri[j]==0) break;
  72. }
  73. }
  74. }
  75. int main()
  76. {
  77. getP(M);int A,B,C;
  78. while (~scanf("%d%d%d",&A,&B,&C),A+B+C){
  79. int len=1;while(len<=B) len<<=1;len<<=2;
  80. for (int i=0;i<=len;i++) s[i]=h[i]=c[i]=d[i]=complex(0,0);
  81. for(int i=0; i<B; ++i) if(vis[i]) s[i]=h[i]=c[i]=d[i]=complex(1,0);
  82. for (int i=0;i<C;i++){
  83. char ch[3];
  84. scanf("%s",ch);
  85. int ln=strlen(ch),t;
  86. sscanf(ch,"%d",&t);
  87. if (ch[ln-1]=='S') s[t].l=0;
  88. if (ch[ln-1]=='H') h[t].l=0;
  89. if (ch[ln-1]=='C') c[t].l=0;
  90. if (ch[ln-1]=='D') d[t].l=0;
  91. }
  92. fft(s,len,1);fft(h,len,1);
  93. fft(c,len,1);fft(d,len,1);
  94. for (int i=0;i<=len;i++) h[i]=h[i]*s[i]*c[i]*d[i];
  95. fft(h,len,-1);
  96. for (int i=A;i<=B;i++) printf("%.0f\n",fabs((double)h[i].l));
  97. puts("");
  98. }
  99. }

发表评论

表情:
评论列表 (有 0 条评论,157人围观)

还没有评论,来说两句吧...

相关阅读

    相关 UVA11752 The Super Powers

    最近几天的状态着实不好,数电设计的答辩不能更逗,万幸是终于到家了,看到群里有各种群赛十分开心,希望能找回刷题的动力,调整下状态。 这道题是很久前做的,细节记不太清了。。。