题目

Source

http://acm.hust.edu.cn/vjudge/problem/23590

Description

I have a set of super poker cards, consisting of an infinite number of cards. For each positive composite integer p, there are exactly four cards whose value is p: Spade(S), Heart(H), Club(C) and Diamond(D). There are no cards of other values. By “composite integer”, we mean integers that have more than 2 divisors. For example, 6 is a composite integer, since it has 4 divisors: 1, 2, 3, 6; 7 is not a composite number, since 7 only has 2 divisors: 1 and 7. Note that 1 is not composite (it has only 1 divisor).

Given a positive integer n, how many ways can you pick up exactly one card from each suit (i.e. exactly one spade card, one heart card, one club card and one diamond card), so that the card values sum to n? For example, if n=24, one way is 4S+6H+4C+10D, shown below:

Unfortunately, some of the cards are lost, but this makes the problem more interesting. To further make the problem even more interesting (and challenging!), I’ll give you two other positive integers a and b, and you need to find out all the answers for n=a, n=a+1, …, n=b.

Input

The input contains at most 25 test cases. Each test case begins with 3 integers a, b and c, where c is the number of lost cards. The next line contains c strings, representing the lost cards. Each card is formatted as valueS, valueH, valueC or valueD, where value is a composite integer. No two lost cards are the same. The input is terminated by a=b=c=0. There will be at most one test case where a=1, b=50,000 and c<=10,000. For other test cases, 1<=a<=b<=100, 0<=c<=10.

Output

For each test case, print b-a+1 integers, one in each line. Since the numbers might be large, you should output each integer modulo 1,000,000. Print a blank line after each test case.

Sample Input

12 20 2
4S 6H
0 0 0

Sample Output

0
0
0
0
0
0
1
0
3

分析

题目大概说有一副数字是合数的扑克,花色同样有4种,现在已知里面缺少了c张牌,问从各个花色中各选一张,分别有多少种方案使得四张牌的和等于[a,b]中的各个数字。

母函数,构造四个多项式,分别对应各个花色,指数表示牌上面的数字,系数表示该牌的数量(0或1),然后四个多项式乘积中指数等于[a,b]的系数就是答案了。

由于指数达到了50000,所以用FFT进行多项式乘法。

这题还是很容易的,不过还是WA了——因为精度。。要用long double。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<algorithm>
  5. using namespace std;
  6. #define MAXN 277777
  7. const long double PI=acos(-1.0);
  8.  
  9. struct Complex{
  10. long double real,imag;
  11. Complex(long double _real,long double _imag):real(_real),imag(_imag){}
  12. Complex(){}
  13. Complex operator+(const Complex &cp) const{
  14. return Complex(real+cp.real,imag+cp.imag);
  15. }
  16. Complex operator-(const Complex &cp) const{
  17. return Complex(real-cp.real,imag-cp.imag);
  18. }
  19. Complex operator*(const Complex &cp) const{
  20. return Complex(real*cp.real-imag*cp.imag,real*cp.imag+cp.real*imag);
  21. }
  22. void setValue(long double _real=0,long double _imag=0){
  23. real=_real; imag=_imag;
  24. }
  25. };
  26.  
  27. int len;
  28. Complex wn[MAXN],wn_anti[MAXN];
  29.  
  30. void FFT(Complex y[],int op){
  31. for(int i=1,j=len>>1,k; i<len-1; ++i){
  32. if(i<j) swap(y[i],y[j]);
  33. k=len>>1;
  34. while(j>=k){
  35. j-=k;
  36. k>>=1;
  37. }
  38. if(j<k) j+=k;
  39. }
  40. for(int h=2; h<=len; h<<=1){
  41. Complex Wn=(op==1?wn[h]:wn_anti[h]);
  42. for(int i=0; i<len; i+=h){
  43. Complex W(1,0);
  44. for(int j=i; j<i+(h>>1); ++j){
  45. Complex u=y[j],t=W*y[j+(h>>1)];
  46. y[j]=u+t;
  47. y[j+(h>>1)]=u-t;
  48. W=W*Wn;
  49. }
  50. }
  51. }
  52. if(op==-1){
  53. for(int i=0; i<len; ++i) y[i].real/=len;
  54. }
  55. }
  56. void Convolution(Complex A[],Complex B[],int n){
  57. for(len=1; len<(n<<1); len<<=1);
  58. for(int i=n; i<len; ++i){
  59. A[i].setValue();
  60. B[i].setValue();
  61. }
  62.  
  63. FFT(A,1); FFT(B,1);
  64. for(int i=0; i<len; ++i){
  65. A[i]=A[i]*B[i];
  66. }
  67. FFT(A,-1);
  68. }
  69.  
  70. bool isComNum[55555];
  71. bool exist[4][55555];
  72. Complex A[4][MAXN];
  73.  
  74. int main(){
  75. for(long long i=2; i<55555; ++i){
  76. if(!isComNum[i]){
  77. for(long long j=i*i; j<55555; j+=i){
  78. isComNum[j]=1;
  79. }
  80. }
  81. }
  82. for(int i=0; i<MAXN; ++i){
  83. wn[i].setValue(cos(2.0*PI/i),sin(2.0*PI/i));
  84. wn_anti[i].setValue(wn[i].real,-wn[i].imag);
  85. }
  86. int a,b,c;
  87. while(scanf("%d%d%d",&a,&b,&c)==3 && (a||b||c)){
  88. memset(exist,1,sizeof(exist));
  89. char ch; int x;
  90. while(c--){
  91. scanf("%d",&x); scanf(" %c",&ch);
  92. if(ch=='S') exist[0][x]=0;
  93. else if(ch=='H') exist[1][x]=0;
  94. else if(ch=='C') exist[2][x]=0;
  95. else exist[3][x]=0;
  96. }
  97. for(int i=0; i<4; ++i){
  98. for(int j=0; j<b; ++j){
  99. if(isComNum[j] && exist[i][j]) A[i][j].setValue(1);
  100. else A[i][j].setValue(0);
  101. }
  102. }
  103. Convolution(A[0],A[1],b);
  104. Convolution(A[2],A[3],b);
  105. Convolution(A[0],A[2],b*2);
  106. for(int i=a; i<=b; ++i){
  107. printf("%lld\n",(long long)(A[0][i].real+0.5));
  108. }
  109. putchar('\n');
  110. }
  111. return 0;
  112. }

UVa12298 Super Poker II(母函数 + FFT)的更多相关文章

  1. UVA12298 Super Poker II

    怎么又是没人写题解的UVA好题,个人感觉应该是生成函数的大板子题了. 直接做肯定爆炸,考虑来一发优化,我们记一个多项式,其中\(i\)次项的系数就表示对于\(i\)这个数有多少种表示方式. 那么很明显 ...

  2. UVA - 12298 Super Poker II NTT

    UVA - 12298 Super Poker II NTT 链接 Vjudge 思路 暴力开个桶,然后统计,不过会T,用ntt或者fft,ntt用个大模数就行了,百度搜索"NTT大模数&q ...

  3. bzoj2487: Super Poker II

    Description I have a set of super poker cards, consisting of an infinite number of cards. For each p ...

  4. Super Poker II UVA - 12298 FFT_生成函数

    Code: #include<bits/stdc++.h> #define maxn 1000000 #define ll long long #define double long do ...

  5. UVA - 12298 Super Poker II (FFT+母函数)

    题意:有四种花色的牌,每种花色的牌中只能使用数值的约数个数大于2的牌.现在遗失了c张牌.每种花色选一张,求值在区间[a,b]的每个数值的选择方法有多少. 分析:约数个数大于2,即合数.所以先预处理出5 ...

  6. FFT(快速傅里叶变换):UVAoj 12298 - Super Poker II

    题目:就是现在有一堆扑克里面的牌有无数张, 每种合数的牌有4中不同花色各一张(0, 1都不是合数), 没有质数或者大小是0或者1的牌现在这堆牌中缺失了其中的 c 张牌, 告诉你a, b, c接下来c张 ...

  7. UVA 12298 Super Poker II (FFT)

    #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using ...

  8. 关于网上quartus ii 生成fft核出现问题解决

    ------------恢复内容开始------------ 关于网上quartus ii 生成fft核出现问题解决 1:必须把软件破解啦 2:必须把IP核破解啦 破解步骤网上也有可以直接看,一定要全 ...

  9. SPOJ:Triple Sums(母函数+FFT)

    You're given a sequence s of N distinct integers.Consider all the possible sums of three integers fr ...

随机推荐

  1. 最长公共上升子序列(codevs 2185)

    题目描述 Description 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序列了. 小沐沐说,对 ...

  2. UVa1593_Allgnment_Of_Code

    /** start: integer; // begins hear stop: integer; // ends here s: string; c: char; // temp **/ //测试数 ...

  3. Runtime.getRuntime().exec()

    Runtime.getRuntime()返回当前应用程序的Runtime对象,该对象 的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实 ...

  4. 20145206邹京儒《Java程序设计》课程总结

    20145206邹京儒<Java程序设计>课程总结 (按顺序)每周读书笔记链接汇总 第一周:http://www.cnblogs.com/ZouJR/p/5213572.html http ...

  5. 标准BT.656并行数据结构

    转自网络,感谢原作者和转载者. 还有参考:百科http://baike.baidu.com/link?url=bqBT3S7pz_mRJoQE7zkE0K-R1RgQ6FmHNOZ0EjhlSAN_o ...

  6. 【转载】 Pyqt QStackedWidget堆栈窗体

    转载地址: http://blog.csdn.net/a649518776/article/details/6636578 下面用代码实现上面窗口的设计 # -*- coding: utf-8 -*- ...

  7. 深入理解JavaScript定时机制和定时器注意问题

    容易欺骗别人感情的JavaScript定时器 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不 ...

  8. 数据结构之图 Part3 – 2 遍历

    BFS using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  9. wp8 入门到精通 聊天控件

    <Grid > <Grid x:Name="bubble_right" VerticalAlignment="Center" RenderTr ...

  10. C# 创建Windows Service

    当我们需要一个程序长期运行,但是不需要界面显示时可以考虑使用Windows Service来实现.这篇博客将简单介绍一下如何创建一个Windows Service,安装/卸载Windows Servi ...