hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】...
题目链接
首先利用组合数学知识,枚举两人的总胜场数容易得到
这还不是卷积的形式,直接搞的话复杂度大概是O(n^2)的,肯定会TLE。但似乎和卷积有点像?想半天没想出来。。多谢Q巨提醒,才知道可以用下面这个公式进行转化
最后,化得的公式为
另外注意,上式右边是一个卷积的形式,但是,所得和的第一项是不需要加上的(不过图中公式没有体现)。结合实际意义大概就是,i==0&&j==0时,gcd(i,j)不存在约数d,虽然0可以被任意正整数整除 & 第一项不为0
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef double db; #define upmo(a,b) (((a)=((a)+(b))%mod)<0?(a)+=mod:(a)) // 相加后取模 int n,mod;namespace FFT_MO //前面需要有 mod(1e8~1e9级别),upmo(a,b) 的定义 {const int FFT_MAXN=1<<18;const db pi=3.14159265358979323846264338327950288L;struct cp{db a,b;cp(double a_=0,double b_=0){a=a_,b=b_;}cp operator +(const cp&rhs)const{return cp(a+rhs.a,b+rhs.b);}cp operator -(const cp&rhs)const{return cp(a-rhs.a,b-rhs.b);}cp operator *(const cp&rhs)const{return cp(a*rhs.a-b*rhs.b,a*rhs.b+b*rhs.a);}cp operator !()const{return cp(a,-b);}}nw[FFT_MAXN+1],f[FFT_MAXN],g[FFT_MAXN],t[FFT_MAXN]; //a<->f,b<->g,t<~>c int bitrev[FFT_MAXN]; void fft_init() //初始化 nw[],bitrev[] {int L=0;while((1<<L)!=FFT_MAXN) L++;for(int i=1;i<FFT_MAXN;i++) bitrev[i]=bitrev[i>>1]>>1|((i&1)<<(L-1));for(int i=0;i<=FFT_MAXN;i++) nw[i]=cp((db)cosl(2*pi/FFT_MAXN*i),(db)sinl(2*pi/FFT_MAXN*i));}// n已保证是2的整数次幂 // flag=1:DFT | flag=-1: IDFTvoid dft(cp *a,int n,int flag=1) {int d=0;while((1<<d)*n!=FFT_MAXN) d++;for(int i=0;i<n;i++) if(i<(bitrev[i]>>d))swap(a[i],a[bitrev[i]>>d]); // NOTICE!for(int l=2;l<=n;l<<=1){int del=FFT_MAXN/l*flag; // 决定 wn是在复平面是顺时针还是逆时针变化,以及变化间距 for(int i=0;i<n;i+=l) // ????????????????? {cp *le=a+i,*ri=a+i+(l>>1); // ?????????????????cp *w=flag==1? nw:nw+FFT_MAXN; // 确定wn的起点 for(int k=0;k<(l>>1);k++){cp ne=*ri * *w;*ri=*le-ne,*le=*le+ne;le++,ri++,w+=del;}}}if(flag!=1) for(int i=0;i<n;i++) a[i].a/=n,a[i].b/=n;}// convo(a,n,b,m,c) a[0..n]*b[0..m] -> c[0..n+m]void convo(LL *a,int n,LL *b,int m,LL *c){for(int i=0;i<=n+m;i++) c[i]=0;int N=2;while(N<=n+m) N<<=1; // N是c扩展后的长度 for(int i=0;i<N;i++) //扩展 a[],b[] ,存入f[],g[],注意取模 {LL aa=i<=n?a[i]:0,bb=i<=m? b[i]:0; aa%=mod,bb%=mod;f[i]=cp(db(aa>>15),db(aa&32767));g[i]=cp(db(bb>>15),db(bb&32767));}dft(f,N),dft(g,N);for(int i=0;i<N;i++) // 频域求积 // ????????????????? {int j=i? N-i:0;t[i]=((f[i]+!f[j])*(!g[j]-g[i])+(!f[j]-f[i])*(g[i]+!g[j]))*cp(0,0.25);}dft(t,N,-1);for(int i=0;i<=n+m;i++) upmo(c[i],(LL(t[i].a+0.5))%mod<<15);for(int i=0;i<N;i++) // 频域求积 // ????????????????? {int j=i? N-i:0;t[i]=(!f[j]-f[i])*(!g[j]-g[i])*cp(-0.25,0)+cp(0,0.25)*(f[i]+!f[j])*(g[i]+!g[j]);}dft(t,N,-1);for(int i=0;i<=n+m;i++) upmo(c[i],LL(t[i].a+0.5)+(LL(t[i].b+0.5)%mod<<30));} }//==============预处理阶乘及阶乘逆元============== LL qpow(LL x,LL n) //求x^n%mod {LL ret=1;for(; n; n>>=1){if(n&1) ret=ret*x%mod;x=x*x%mod;}return ret; } LL inv(LL x) {return qpow(x,mod-2); } const LL M=1e5+5; LL fac[M+5]; //阶乘 LL inv_of_fac[M+5]; //阶乘的逆元 void init_fac() {fac[0]=1;for(int i=1; i<=M; i++)fac[i]=fac[i-1]*i%mod;inv_of_fac[M]=qpow(fac[M],mod-2);for(int i=M-1; i>=0; i--)inv_of_fac[i]=inv_of_fac[i+1]*(i+1)%mod; } //================================================//===================phi(x)打表===================const int maxn=100007; int phi[maxn+5]; void init_phi() {memset(phi,0,sizeof(phi)); //初始化为0phi[1]=1;for(int i=2; i<=maxn; i++){if(!phi[i]) //当i是质数时for(int j=i; j<=maxn; j+=i) //筛选所有因子为i的数 {if(!phi[j]) phi[j]=j; //若未赋值过,先初始化phi[j]=phi[j]/i*(i-1); //i是质因数(1-1/i)=(i-1)/i,先除再乘是为了防止越界。 }} } //================================================ LL a[1<<18|1],b[1<<18|1],c[1<<18|1];int main() {init_phi();FFT_MO::fft_init();//=============debug==============// int n,m; // mod=1e9+7; // while(cin>>n>>m) // { // for(int i=0;i<=n;i++) cin>>a[i]; // for(int i=0;i<=m;i++) cin>>b[i]; // FFT_MO::convo(a,n,b,m,c); // for(int i=0;i<=n+m;i++) // cout<<c[i]<<' '; // puts(""); // }//================================int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&mod);init_fac();LL ans=0;for(int d=1;d<=n;d++){int N=n/d;for(int i=0;i<=N;i++) a[i]=b[i]=inv_of_fac[i*d];FFT_MO::convo(a,N,b,N,c);LL temp=0;for(int i=1;i<=N;i++) temp=(temp+c[i]*inv_of_fac[n-i*d])%mod;ans=(ans+temp*phi[d])%mod;}ans=ans*fac[n]%mod*qpow(3,n)%mod;printf("%lld\n",ans);} }
关于模意义下的FFT
转载于:https://www.cnblogs.com/Just--Do--It/p/7346532.html
hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】...相关推荐
- 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FFT)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FF ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)...
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- Python编程基础:第三十七节 石头剪刀布游戏Rock, Paper, Scissors Game
第三十七节 石头剪刀布游戏Rock, Paper, Scissors Game 前言 实践 前言 我们这一节的内容主要是对前边学习内容的一个综合应用,以石头,剪刀,布游戏为例讲解列表.随机数.用户输入 ...
- 【Codeforces 1426 E】Rock, Paper, Scissors,贪心!算反面
problem E. Rock, Paper, Scissors time limit per test1 second memory limit per test256 megabytes inpu ...
- 2017多校第3场 HDU 6058 Kanade's sum 双链表,思维
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题外话:这场多校,真心感觉自己的无力,全队都发挥的很差,结束的时候排名掉到了90多,后期没做出字 ...
- 计蒜客A1676 Rock Paper Scissors Lizard Spock
链接 https://nanti.jisuanke.com/t/A1676 题解 每种分开算,比如我先考虑出 s c i s s o r s scissors scissors,把模式串中的所有 S ...
- CodeForces - 1426E Rock, Paper, Scissors(最小费用最大流+最大费用最大流)
题目链接:点击查看 题目大意:A 和 B 在玩石头剪刀布,A 会出 a1 次石头,a2 次剪刀,a3 次布,同理 B 会出 b1 次石头,b2 次剪刀,b3 次布,若对战顺序是可以进行决定的,问 A ...
- Problem H Rock Paper Scissors,FFT
题目 题目链接 题意 给出两段石头剪刀布的顺序SSS和T" role="presentation" style="position: relative;&quo ...
- 2017多校第4场 HDU 6078 Wavel Sequence DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:求两个序列的公共波形子序列的个数. 解法: 类似于最长公共上升子序列,对于每个i,只考虑存 ...
- 2017 多校训练第二场 HDU 6047 Maximum Sequence(贪心+优先队列)
Maximum Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
最新文章
- 日志模块 logging
- LLVM笔记(1) - TableGen
- Java的synchronized关键字:同步机制总结
- C++一维数组和指针的关系总结
- C++ 对象内存布局 (4)
- 吃相难看!它又又又涨价了......
- mysql批量导入txt数据_MySQL批量导入Excel、txt数据
- Ubuntu source insight3稳定性
- springmvc源码解析MvcNamespaceHandler之mvc:default-servlet-handler/
- 编辑PDF文档无需购买会员;流失与版式分别是什么,PDF与OFD又有什么区别
- Vue项目实战之电商后台管理系统(三) 用户管理模块
- 【苹果相册推】群发安装软件设备推送通知SSL允许证
- 发布一篇通过foxmail订阅rss的方法
- Assigned 函数
- 《Java入门》简化的插入排序:本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序。
- Dell E515dn 驱动
- 隐身专家 v2.81 绿色
- 企业邮箱容量,注册无限容量邮箱,企业邮箱服务器怎么设置?
- MAC下SSH及可视化工具(亲测有效)
- electron-builder打包工具的最简化使用