题目链接

首先利用组合数学知识,枚举两人的总胜场数容易得到

这还不是卷积的形式,直接搞的话复杂度大概是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】...相关推荐

  1. 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FFT)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FF ...

  2. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)...

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  3. Python编程基础:第三十七节 石头剪刀布游戏Rock, Paper, Scissors Game

    第三十七节 石头剪刀布游戏Rock, Paper, Scissors Game 前言 实践 前言 我们这一节的内容主要是对前边学习内容的一个综合应用,以石头,剪刀,布游戏为例讲解列表.随机数.用户输入 ...

  4. 【Codeforces 1426 E】Rock, Paper, Scissors,贪心!算反面

    problem E. Rock, Paper, Scissors time limit per test1 second memory limit per test256 megabytes inpu ...

  5. 2017多校第3场 HDU 6058 Kanade's sum 双链表,思维

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6058 题外话:这场多校,真心感觉自己的无力,全队都发挥的很差,结束的时候排名掉到了90多,后期没做出字 ...

  6. 计蒜客A1676 Rock Paper Scissors Lizard Spock

    链接 https://nanti.jisuanke.com/t/A1676 题解 每种分开算,比如我先考虑出 s c i s s o r s scissors scissors,把模式串中的所有 S ...

  7. CodeForces - 1426E Rock, Paper, Scissors(最小费用最大流+最大费用最大流)

    题目链接:点击查看 题目大意:A 和 B 在玩石头剪刀布,A 会出 a1 次石头,a2 次剪刀,a3 次布,同理 B 会出 b1 次石头,b2 次剪刀,b3 次布,若对战顺序是可以进行决定的,问 A ...

  8. Problem H Rock Paper Scissors,FFT

    题目 题目链接 题意 给出两段石头剪刀布的顺序SSS和T" role="presentation" style="position: relative;&quo ...

  9. 2017多校第4场 HDU 6078 Wavel Sequence DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:求两个序列的公共波形子序列的个数. 解法: 类似于最长公共上升子序列,对于每个i,只考虑存 ...

  10. 2017 多校训练第二场 HDU 6047 Maximum Sequence(贪心+优先队列)

    Maximum Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

最新文章

  1. 日志模块 logging
  2. LLVM笔记(1) - TableGen
  3. Java的synchronized关键字:同步机制总结
  4. C++一维数组和指针的关系总结
  5. C++ 对象内存布局 (4)
  6. 吃相难看!它又又又涨价了......
  7. mysql批量导入txt数据_MySQL批量导入Excel、txt数据
  8. Ubuntu source insight3稳定性
  9. springmvc源码解析MvcNamespaceHandler之mvc:default-servlet-handler/
  10. 编辑PDF文档无需购买会员;流失与版式分别是什么,PDF与OFD又有什么区别
  11. Vue项目实战之电商后台管理系统(三) 用户管理模块
  12. 【苹果相册推】群发安装软件设备推送通知SSL允许证
  13. 发布一篇通过foxmail订阅rss的方法
  14. Assigned 函数
  15. 《Java入门》简化的插入排序:本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序。
  16. Dell E515dn 驱动
  17. 隐身专家 v2.81 绿色
  18. 企业邮箱容量,注册无限容量邮箱,企业邮箱服务器怎么设置?
  19. MAC下SSH及可视化工具(亲测有效)
  20. electron-builder打包工具的最简化使用

热门文章

  1. 华为WLAN产品介绍
  2. 华三 h3c 单臂路由配置
  3. NoSQL之MongoDB复制集配置、数据导出导入
  4. Leetcode 刷题笔记(二十九) ——动态规划篇之子序列问题:编辑距离
  5. 我要做 Android 之面笔试
  6. tortoisegit 还原到某个版本
  7. Mybatis配置映射文件中parameterType的用法小结
  8. ubuntu 10.04 源
  9. NHibernate3.0里各个dll的用处和简单说明【转】
  10. 杭电1.3.6考试排名