zoukankan      html  css  js  c++  java
  • UVA12298 Super Poker II

    怎么又是没人写题解的UVA好题,个人感觉应该是生成函数的大板子题了。

    直接做肯定爆炸,考虑来一发优化,我们记一个多项式,其中(i)次项的系数就表示对于(i)这个数有多少种表示方式。

    那么很明显,我们可以先筛素数,那么初始的多项式只有范围的的素数对应项系数才为(1),否则都为(0)

    然后考虑两种花色配对,其实就是看任意两张牌上面的数字加起来能得到什么。

    说具体点就是配对后某个项的系数就是两种花色中项的次数之和为这个次数的所有系数之和。

    所以我们发现配对的本质其实就是卷积,那么就可以用FFT优化之了。

    注意这题有点卡精度,需要开一波long double才能过。

    CODE

    #include<cstdio>
    #include<cctype>
    #include<cmath>
    #define RI register int
    using namespace std;
    typedef long double DB;
    const DB pi=acos(-1);
    const int N=50005;
    struct Complex
    {
        DB x,y;
        Complex(DB X=0,DB Y=0) { x=X; y=Y; }
    }S[N<<3],H[N<<3],C[N<<3],D[N<<3]; int a,b,c,rev[N<<3],prime[N+5],cnt,lim=1,p,x; bool vis[N+5]; char opt;
    inline Complex operator +(Complex A,Complex B) { return Complex(A.x+B.x,A.y+B.y); }
    inline Complex operator -(Complex A,Complex B) { return Complex(A.x-B.x,A.y-B.y); }
    inline Complex operator *(Complex A,Complex B) { return Complex(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x); }
    class FFT_Solver
    {
        private:
            inline void swap(Complex &x,Complex &y)
            {
                Complex t=x; x=y; y=t;
            }
        public:
            inline void init(int n)
            {
                lim=1; p=0; while (lim<=n) lim<<=1,++p; lim<<=2; p+=2;
                for (RI i=0;i<lim;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<p-1);
            }
            inline void FFT(Complex *f,int opt)
            {
                RI i; for (i=0;i<lim;++i) if (i<rev[i]) swap(f[i],f[rev[i]]);
                for (i=1;i<lim;i<<=1)
                {
                    Complex D(cos(pi/i),opt*sin(pi/i));
                    int m=i<<1; for (RI j=0;j<lim;j+=m)
                    {
                        Complex W(1,0); for (RI k=0;k<i;++k,W=W*D)
                        {
                            Complex x=f[j+k],y=W*f[i+j+k];
                            f[j+k]=x+y; f[i+j+k]=x-y;
                        }
                    }
                }
            }
    }F;
    #define Pi prime[j]
    inline void Euler(int n)
    {
        for (RI i=2;i<=n;++i)
        {
            if (!vis[i]) prime[++cnt]=i;
            for (RI j=1;j<=cnt&&i*Pi<=n;++j)
            {
                vis[i*Pi]=1; if (i%Pi==0) break;
            }
        }
    }
    #undef Pi
    int main()
    {
        Euler(N); while (scanf("%d%d%d",&a,&b,&c),a)
        {
            RI i; for (F.init(b),i=0;i<=b;++i) S[i]=H[i]=C[i]=D[i]=Complex(vis[i],0);
            for (i=b+1;i<lim;++i) S[i]=H[i]=C[i]=D[i]=Complex(0,0);
            for (i=1;i<=c;++i)
            {
                scanf("%d%c",&x,&opt); switch (opt)
                {
                    case 'S':S[x]=Complex(0,0);break;
                    case 'H':H[x]=Complex(0,0);break;
                    case 'C':C[x]=Complex(0,0);break;
                    case 'D':D[x]=Complex(0,0);break;
                }
            }
            for (F.FFT(S,1),F.FFT(H,1),F.FFT(C,1),F.FFT(D,1),i=0;i<lim;++i)
            S[i]=S[i]*H[i]*C[i]*D[i]; F.FFT(S,-1);
            for (i=a;i<=b;++i) printf("%lld
    ",(long long)(S[i].x/lim+0.5)); putchar('
    ');
        }
        return 0;
    }
    
  • 相关阅读:
    2014-9-思杨的缺点
    2014-8-9月杂记
    2014-7-31 思杨在老家想我们
    生日。金鼎轩吃饭;亿旺中影看《后会无期》。
    2014-7-5~6 秦皇岛之旅,带思杨看大海
    2014-6-23 去未来幼儿园玩————————
    2014-6-15 思杨的成长是全家人的责任。
    2014-6-14 思杨跳抓钱舞---疾驰的扭扭车和思杨司机
    2014-6-7 带思杨去西三旗儿童乐园玩-----思杨晕车了
    springboot学习之一
  • 原文地址:https://www.cnblogs.com/cjjsb/p/10300799.html
Copyright © 2011-2022 走看看