【JZOJ100209】【20190705】狂妄之人
题目
\(S\)串长为\(n\),字符集大小为\(k\)
一次操作为:取走\(S\)的任意一个字符或将\(S\)重排为一个没有出现过的字符\(S'\)
询问有多少个\(S\)使得后手必胜,答案对\(P\)取模
$n \le 3 \times 10^5 , k \le 10^9 , 10^8 \le P \le 10^9+100 $
题解
part 1 博弈
先手必败当且仅当\(n\)为偶数,且不同的重排字符个数为奇数(难怪所有sample没有一个n为奇数)
设每一个字符出现的次数为\(a_i\),不同的个数为\((^{ \ \ \ \ \ n }_{a_1 \ a_2 \cdots \ a_k})\)
对n=1显然成立
如果\(n\)为偶数,\(n-1\)为奇数
这时删掉这个字符的人一定是必拜的
如果不同个数为偶数,删掉一个字符的一定是后手,否则一定是先手
如果\(n\)为奇数,刪去一个字符\(i\)相当于将方案乘以\(\frac{a_i}{n}\)
考虑重排数为奇数,一定存在一个$a_i $为奇数,先手操作这个数必胜
考虑重排数为偶数,由于\(n\)为奇数,到时n-1的个数一定仍然为偶数
这时删掉字符的人输,而删掉字符的人一定是后手
所以结论成立
part 2 计数部分
问题变成求$(^{ n }_{a_1 a_2 \cdots a_k}) % 2 = 1 , \sum a_i =n $的个数
\((^n_{a_1 , \cdots , a_k})\) %P 不为0当且仅当拆分成P进制之后\(a1 \& \cdots \& a_k = 0\)
考虑集合幂级数\(F(x) = \sum \frac{1}{i!}\) ,相当于求\(F(x)\)子集卷积的\(k\)次幂
这可以用全家桶的exp和ln优化
part 3 ln和exp
如果直接用\(nlog \ n\)的exp和ln,乘法长度会从18变成32,常数巨大
所以需要用\(n^2\)的多项式exp和ln(pty讲述了一下推法)
考虑f和exp(f)的关系等价于无向连通图的EGF和无向图的EGF之间的关系
考虑暴力地递推:
\[ \begin{align} &考虑G(x)为连通图个数的EGF,F(x)为无向图个数的EGF:\\ &考虑无向连通图和无向图之间的递推\\ &\begin{cases} F_i = \frac{f_i}{i!} \ \ , \ \ G_i = \frac{g_i}{i!}\\ F = exp(G) \\ f_i = \sum_{j=1}^{i} (^i_{j-1}) g_i f_{i-j} \\ \end{cases} 化简得:\\ &\begin{cases} G_0 = 0 \ , \ F_0 = 1\\ F_i = \frac{1}{i}\sum_{j=1}^{i} jG_jF_{i-j}\\ G_i = F_i - \frac{1}{i}\sum_{j=1}^{i-1}jG_jF_{i-j}\\ \end{cases} \end{align} \]
这样就可以做到\(n^2\)时间复杂度\(O(n \ log ^2 n )\)
Code
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define rg register
using namespace std;
const int N=1<<19,M=20;
int n,m,mx,P,L,a[M][N],cnt[N],b[N],c[N],ny[N],fac[N],inv[N];ll lim;
il void inc(int&x,int y){x+=y;if(x>=P)x-=P;}
il void dec(int&x,int y){x-=y;if(x<0)x+=P;}
il void fwt(int*A){for(rg int i=1;i<L;i<<=1)for(rg int j=0;j<L;j+=i<<1)for(rg int k=0;k<i;++k){inc(A[j+k+i],A[j+k]);}
}
il void ifwt(int*A){for(rg int i=1;i<L;i<<=1)for(rg int j=0;j<L;j+=i<<1)for(rg int k=0;k<i;++k){dec(A[j+k+i],A[j+k]);}
}
il void exp(int*A,int*B,int l){B[0]=1;for(rg int i=1;i<=l;++i){B[i]=0;ll t=0;for(rg int j=1;j<=i;++j){//inc(B[i],1ll*j*A[j]%P*B[i-j]%P);t+=1ll*A[j]*B[i-j]%lim*j;if(t>=lim)t-=lim;}//B[i]=1ll*B[i]*ny[i]%P;B[i]=(t%P)*ny[i]%P;}
}
il void ln(int*A,int*B,int l){B[0]=0;for(int i=1;i<=l;++i){B[i]=0;ll t=0;for(rg int j=1;j<i;++j){//dec(B[i],1ll*j*B[j]%P*A[i-j]%P);t+=1ll*B[j]*A[i-j]%lim*j;if(t>=lim)t-=lim;}//B[i]=(A[i]+1ll*B[i]*ny[i])%P;B[i]=(A[i]+(P-t%P)*ny[i])%P;}
}
il void pow(int*A,int k,int l){static int t1[N]; ln(A,t1,l);for(int i=0;i<=l;++i)t1[i]=1ll*t1[i]*k%P;exp(t1,A,l);
}
int main(){freopen("megalovania.in","r",stdin);freopen("megalovania.out","w",stdout);scanf("%d%d%d",&n,&m,&P);if(n&1)return puts("0"),0;lim=(ll)4e18/P*P;L=1;while(L<=n)L<<=1;ny[1]=1;for(int i=2;i<=n;++i)ny[i]=1ll*(P-P/i)*ny[P%i]%P;for(int i=fac[0]=inv[0]=1;i<=n;++i){fac[i]=1ll*fac[i-1]*i%P;inv[i]=1ll*inv[i-1]*ny[i]%P;cnt[i]=cnt[i>>1]+(i&1);}mx=cnt[n];for(int i=0;i<=n;++i)if((i|n)==n)a[cnt[i]][i]=inv[i];for(int i=0;i<=mx;++i)fwt(a[i]);for(int i=0;i<=n;++i)if((i|n)==n){for(int j=0;j<=mx;++j)b[j]=a[j][i];pow(b,m,mx);c[i]=b[mx];}ifwt(c);int ans=1ll*c[n]*fac[n]%P;cout<<ans<<endl;return 0;
}
转载于:https://www.cnblogs.com/Paul-Guderian/p/11148048.html
【JZOJ100209】【20190705】狂妄之人相关推荐
- 音乐计算机曲谱狂妄之人,undertale狂妄之人简谱
undertale狂妄之人简谱是一款玩法类似别踩白块的音乐节奏游戏.游戏中收录了大量传说之下里的战斗曲,玩家可以自由选择自己喜爱的曲目进行游玩.跟随音乐的节奏快速点击,点错或者漏掉都会导致游戏结束,感 ...
- 狂妄之人音乐计算机乐谱,天谕手游狂妄之人乐谱_狂妄之人乐谱代码分享_3DM手游...
在天谕手游中玩家可以把自己喜欢的歌写进乐谱,在这里小编给大家分享一下狂妄之人这首歌的乐谱代码,喜欢的小伙伴不要错过哦,下面小编给大家带来<天谕手游>狂妄之人乐谱代码分享,不清楚代码的小伙伴 ...
- 狂妄之人怎么用计算机弹,天谕手游狂妄之人乐谱代码分享
天谕手游狂妄之人乐谱代码是什么?狂妄之人是游戏"传说之下"(undertale)主题曲中的一个,当玩家控制的人物走了屠杀线遇到sans的时候会触发的背景音乐.接下来小编为大家带来了 ...
- 狂妄之人计算机音乐,Undertale音乐 MEGALOVANIA 狂妄之人
Introduction MEGALOVANIA 狂妄之人 "Undertale音乐 MEGALOVANIA 狂妄之人" is a MIDI music piece in Anim ...
- 狂妄之人怎么用计算机弹,【B】 Undertale Sans战斗曲 MEGALOVANIA狂妄之人
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 66/+ 988689 55/+ 988689 44/+ 988689 33/+ 988689 66/+ 988689 55/+ 988689 44/+ ...
- 音乐计算机曲谱狂妄之人,【B】 Undertale Sans战斗曲 MEGALOVANIA狂妄之人
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 66/+ 988689 55/+ 988689 44/+ 988689 33/+ 988689 66/+ 988689 55/+ 988689 44/+ ...
- 计算机弹奏sans,【B】 Undertale Sans战斗曲 MEGALOVANIA狂妄之人
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 66/+ 988689 55/+ 988689 44/+ 988689 33/+ 988689 66/+ 988689 55/+ 988689 44/+ ...
- 用计算机弹音乐的歌谱狂妄之人,【B】 Undertale Sans战斗曲 MEGALOVANIA狂妄之人...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 66/+ 988689 55/+ 988689 44/+ 988689 33/+ 988689 66/+ 988689 55/+ 988689 44/+ ...
- 俞敏洪+摆脱恐惧+世界想让你做一个平凡的人、你信了吗
俞敏洪:摆脱恐惧 亲爱的朋友们,亲爱的同学们,大家晚上好! 其实站在这么一个舞台上,我们很多同学都会羡慕,也会想,要是我去讲也许会讲的比他更好.但是他不管面对失败 ...
最新文章
- 用于高亮反光零件缺陷的自动视觉检测系统
- Sudo 漏洞隐患不断,macOS 也受牵连!
- 大数据全体系年终总结
- Smali语法简单介绍
- jquery正则匹配URL地址
- ubuntu 环境下调试mysql源码_Linux中eclipse调试mysql源代码
- mybatis动态查询列名,#与¥
- 元类(metaclass)
- M1 Repast Simphony打不开 无反应问题解决
- 计算机无法进去系统,开机进入bios无法进入系统怎么办_电脑开机就进入bios的解决方法...
- APP渠道推广手册(新手必备)
- 02 离线安装管理ceph图形化界面calamari
- 关于IE、Firefox、Opera页面呈现异同 (转于纯蓝)
- 怎么压缩word文档,word压缩方法介绍
- UTD2102CEX 示波器波形数据导出注意事项
- 墙裂推荐!B站上的Python学习资源
- 校园网免认证上网的方法
- 网易有道词典——截屏翻译时候跳转桌面的一种解决办法
- python提取内容保存excel_Python操作Excel之数据提取
- 解决Ubuntu16.04下wingide6.1无法用五笔输入中文的问题