怎么又是没人写题解的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\n",(long long)(S[i].x/lim+0.5)); putchar('\n');
}
return 0;
}

UVA12298 Super Poker II的更多相关文章

  1. UVa12298 Super Poker II(母函数 + FFT)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/23590 Description I have a set of super poker cards, ...

  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. FFT(快速傅里叶变换):UVAoj 12298 - Super Poker II

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

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

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

  7. UVA 12298 Super Poker II (FFT)

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

  8. 浅谈FFT(快速傅里叶变换)

    本文主要简单写写自己在算法竞赛中学习FFT的经历以及一些自己的理解和想法. FFT的介绍以及入门就不赘述了,网上有许多相关的资料,入门的话推荐这篇博客:FFT(最详细最通俗的入门手册),里面介绍得很详 ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. eclipse中web项目没有run on server

    刷新web项目,项目->右击->Properties->Project Facets,选择Java和Dynamic Web Module.点击Apply and Close,再次运行 ...

  2. python爬虫从入门到放弃(九)之 Requests+正则表达式爬取猫眼电影TOP100

    import requests from requests.exceptions import RequestException import re import json from multipro ...

  3. Keras深度学习框架安装及快速入门

    1.下载安装Keras 如果你是安装的Anaconda组合套件,可以直接在Prompt上执行安装命令:pip install keras 注意:最下面为Successfully...表示安装成功! 2 ...

  4. Linux修改挂载目录名称

    Local系统管理员新增了一个VG,将一个原挂载点/u02改为了/u02-old, 如下所示. [root@mylnx01 ~]# df -h Filesystem            Size  ...

  5. 初学ubuntu命令

    将我第一天学的内容做个笔记 ,方便日后查看 命令的使用: ls     ls -a 显示所有文件  ls -l 显示文件的所有信息 cp   注意命令格式  /home/../temp/a   /ho ...

  6. Cs231n课堂内容记录-Lecture1 导论

    Lecture 1 视频网址:https://www.bilibili.com/video/av17204303/?p=2 https://zhuanlan.zhihu.com/p/21930884? ...

  7. 同步下的资源互斥:停运保护(Run-Down Protection)机制

    背景 近期在学习ProcessHacker的源码,Process Hacker是一个免费的.功能强大的"任务管理器",可用于监听系统资源的使用情况,调试软件以及检测恶意程序.使用中 ...

  8. Java的基础知识三

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  9. Docker: docker network 容器网络

    容器网络命令 : docker network --help 常用的是 docker network create/ls/rm/inspect 容器网络类型,一共有以下5种 bridge–net=br ...

  10. org.springframework.dao.InvalidDataAccessResourceUsageException: Unexpected cursor position change. Spring Batch 错误

    在用SpringBatch 跑job的时候出现这个错误, 由于取数据的DB 是netezza, 框架可能支持的不是很全面,当然也可能是其他原因. <bean id="reader_rd ...