居然因为精度问题WA掉了。。。
这题要用long double,并且交c++11……
每种花色的牌开一个系数向量,有这种牌那么系数就是1,否则为0.然后FFT乘起来就行了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
typedef long double real;
const int maxn=262144;
const real pi=acos(-1.0);
//3.1415926535897932384626433832795028841971693993751058209749445923806406;
struct cp{
real r,i;
cp(real _r=0.,real _i=0.):r(_r),i(_i){}
cp operator+(const cp &a){
return cp(r+a.r,i+a.i);
}
cp operator-(const cp &a){
return cp(r-a.r,i-a.i);
}
cp operator*(const cp &a){
return cp(r*a.r-i*a.i,r*a.i+i*a.r);
}
}s[maxn],h[maxn],c[maxn],d[maxn];
int prime[30000],tot;
bool isprime[50001];
void brc(cp y[],int len){
for(int i=1,j=len>>1;i<len-1;++i){
if(i<j) swap(y[i],y[j]);
int k=len>>1;
while(j>=k) j-=k,k>>=1;
j+=k;
}
}
void fft(cp y[],int l,int on){
brc(y,l);
int j,k,h;
cp u,t;
for(h=2;h<=l;h<<=1){
cp wn(cos(on*2*pi/h),sin(on*2*pi/h));
for(int j=0;j<l;j+=h){
cp w(1);
for(int k=j;k<j+h/2;++k){
u=y[k];
t=w*y[k+h/2];
y[k]=u+t;
y[k+h/2]=u-t;
w=w*wn;
}
}
}
if(on==-1) for(int i=0;i<l;++i) y[i].r/=l;
}
void genPrime(int n){
memset(isprime,true,sizeof isprime);
for(int i=2;i<=n;++i){
if(isprime[i])
prime[tot++]=i;
for(int j=0;j<tot&&i*prime[j]<=n;++j){
isprime[i*prime[j]]=false;
if(i%prime[j]==0) break;
}
}
}
void print(long long x){
char a[20]={0};
if(!x) a[0]=1;
while(x) a[++a[0]]=x%10,x/=10;
for(;a[0];--a[0])
putchar(a[a[0]]+48);
putchar('\n');
}
int main(){
int A,B,C;
genPrime(50000);
while(scanf("%d%d%d",&A,&B,&C)==3&&(A||B||C)){
int L=1;
while(L<=B) L<<=1;
L<<=2;
memset(s,0,sizeof s);
memset(h,0,sizeof h);
memset(c,0,sizeof c);
memset(d,0,sizeof d);
for(int i=0;i<B;++i) if(!isprime[i]) s[i].r=1;
for(int i=0;i<B;++i) if(!isprime[i]) h[i].r=1;
for(int i=0;i<B;++i) if(!isprime[i]) c[i].r=1;
for(int i=0;i<B;++i) if(!isprime[i]) d[i].r=1;
for(int i=0;i<C;++i){
char str[20];
scanf("%s",str);
int len=strlen(str),t;
sscanf(str,"%d",&t);
switch(str[len-1]){
case 'S':s[t].r=0;break;
case 'H':h[t].r=0;break;
case 'C':c[t].r=0;break;
case 'D':d[t].r=0;break;
}
}
fft(s,L,1);fft(h,L,1);
fft(c,L,1);fft(d,L,1);
for(int i=0;i<L;++i) h[i]=s[i]*h[i]*c[i]*d[i];
fft(h,L,-1);
for(int i=A;i<=B;++i) printf("%.0lf\n",fabs((double)h[i].r));
putchar('\n');
}
return 0;
}
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
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
Output
For each test case, print
p
(应为
Sample Input
12 20 2
4S 6H
0 0 0
Sample Output
0
0
0
0
0
0
1
0
3