题目

\(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;
}

【JZOJ100209】【20190705】狂妄之人的更多相关文章

  1. Linux是一门真正的黑客高手艺术

    黑客这个词从诞生到现在,从来就没有解释为“高级入侵者”.“病毒制造者”或者“QQ盗号者”过.我至今不清楚在中国是谁先把黑客和这些无聊的词汇联系在了一起,导致如此多的人被误导.但有一点是肯定的,不负责任 ...

  2. KP 佛学禅语

    1.人之所以痛苦,在于追求错误的东西. 2.如果你不给自己烦恼,别人也永远不可能给你烦恼.因为你自己的内心,你放不下. 3.你永远要感谢给你逆境的众生. 4.你永远要宽恕众生,不论他有多坏,甚至他伤害 ...

  3. [转]一个普通IT人的十年回顾---金旭亮

    金旭亮老师十年体会,很有收获.转自网络. 金旭亮于1989年与超级解霸的开发者梁肇新同时迈入广西大学的校门,却走了一条与其不同的路. 1994年起开始自学计算机专业本科课程,并开始编程,从未间断,迄今 ...

  4. CSP-S2019游记 执枪的人,一定要做好被杀的觉悟。

    啊,大概是人生中最镇定的三天了. 是了. Day0 教练超级巨,给了我们电话说出去要散养,有事别慌,打电话.身份证丢了别慌,打电话.火车误了别慌,打电话... 然后去了就路上颓颓颓.然后过去试机,打了 ...

  5. 一个IT人的成长路

    毕业四年多了,来深圳三年多了,经历了刚毕业的懵懂少年,成长为现在的成熟稳重青年.职场上,从刚毕业的小白,成长为现在可以成熟应对各种事情的老司机.经历过从初级研发工程师,到中级研发工程师,到高级研发工程 ...

  6. 通过自定义特性,使用EF6拦截器完成创建人、创建时间、更新人、更新时间的统一赋值(使用数据库服务器时间赋值,接上一篇)

    目录: 前言 设计(完成扩展) 实现效果 扩展设计方案 扩展后代码结构 集思广益(问题) 前言: 在上一篇文章我写了如何重建IDbCommandTreeInterceptor来实现创建人.创建时间.更 ...

  7. BPM始终服务于人,落脚于人

    数字经济时代下,云计算.大数据.移动互联已经成为当下企业必须采取的武装力量.随着互联网+.中国制造2025.工业4.0等国家战略的引导与支持,无数的企业在这场数字化浪潮中使尽浑身解数,想要抓住机遇奋力 ...

  8. 给缺少Python项目实战经验的人

    我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...

  9. 周末聊聊IT人员的人脉观:关于帮妹子找兼职有感

    背景: 前几天,有个认识了好几年的网友,现在是大学生,在厦门读大一,说和她同学要一起到广州找兼职,看我有没有介绍. 像我这么积极热心善良的人,就说帮她找找看,结果问了几次,没消息,只好诚实的回复人家, ...

随机推荐

  1. 怎么写自己的CMakeLists.txt--二

    之前写过一篇及其简单的关于CMakeLists.txt的写法,现在重点剖析find_package的用法. 如果程序中使用了外部库,事先并不知道它的头文件和链接库的位置,就要给出头文件和链接库的查找方 ...

  2. 2018年Java面试题整理

    面试是我们每个人都要经历的事情,大部分人且不止一次,这里给大家总结最新的2018年面试题,让大家在找工作时候能够事半功倍.  1. Switch能否用string做参数? a. 在 Java 7 之前 ...

  3. [转帖]CHROME开发者工具的小技巧

    CHROME开发者工具的小技巧 https://coolshell.cn/articles/17634.html 需要仔细学习看一看呢. 2017年01月19日 陈皓 评论 58 条评论  64,08 ...

  4. SkyWalking6.2.0版本UI参数、告警参数、指标含义中文解释

    一.告警规则相关参数 二.SkyWalking UI相关参数CPM:每分钟请求调用的次数SLA: 服务等级协议(简称:SLA,全称:service level agreement).是在一定开销下为保 ...

  5. 记Flask的一种设置项目配置的方法!

    在做项目时,碰到的一种设置配置的方式,主要是因为公司将所有的配置写成了一个公司专有的配置库(各种资源地址,账号等),上线后的项目需要什么配置是从这个配置库的读取.但在开发时不能使用,所以在开发时需要自 ...

  6. 在ASP.NET Core中添加的Cookie如果含有特殊字符,会被自动转义

    我们知道在Cookie中有些字符是特殊字符,这些字符是不能出现在Cookie的键值中的. 比如"="是Cookie中用来分隔键和值的特殊字符,例如:Key01=Value01,表示 ...

  7. 匿名方法是怎样演变到Lambda表达试过程

    一.  "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda ab ...

  8. ASP.NET Core 3.0 WebApi 系列【1】创建ASP.NET Core WebApi 项目

    目录 写在前面 一.运行环境 二.项目搭建 三.测试 API 四.基础知识 五.写在最后 写在前面 C#语言可以创建RESTful服务,被称作WebApi.在这里总结学习使用支持创建.读取.更新.删除 ...

  9. tempermonkey文档及为google翻译添加清除输入框脚本

    想通过tempermonkey为google增加一个清除输入框的快捷键,这本来是很好做的事情,后来也证明确实是那么简单,不过中间遇到了几个奇怪的问题,有必要记录一下 tempermonkey 文档:h ...

  10. jenkins 配置ssh remotes 报Failed to authenticate with public key

    问题:jenkins配置ssh远程连接时候报 ERROR: Failed to authenticate with public key com.jcraft.jsch.JSchException: ...