【JSWC2019】 小X的咒语
【JSWC2019】 小X的咒语
\(\\\)
首先这道题有三个限制:
- 每个点恰好两个出度和入度。
- 没有自环。
- 没有重边。
我们先定义几个变量:
\(h_{i,j}\):表示有\(i\)个出度入度为\(1\)的点和\(j\)个出度入度为\(2\)的点,可以有重边和自环的方案数。
\(g_{i,j}\):表示有\(i+j\)个出度入度为\(2\)的点,其中\(i\)个不能有自环,\(j\)个可以有自环的方案数。
\(f_{i,j,k}\):有\(i\)个点,这\(i\)个点之间只能连重边,不能连自环,连完边后还剩\(j\)个点没有连出边,其中的\(k\)个点也没有入边的方案数。
\(ans_i\):至少有\(i\)个点连了重边,没有自环的方案数。
求出的\(ans\)过后就可以用容斥来算答案:
\]
考虑求\(ans_i\):
\]
有\(n-m\)个点还没有连出边,假设这其中有\(i\)个点也没有入边,那么这\(i\)个点不能连出自环,另外的\(n-m-i\)的点不可能连出自环。
考虑求\(f\):
用\(DP\)来求。考虑每次新加入一个点,它与之前的点的连边情况,具体方程就看代码吧。
考虑求\(g\):
同样是用容斥。算至少有\(i\)个点连出自环的方案数。
\]
枚举\(i\)个点有自环,那么我们就先让这\(i\)个点都向自己连一条边,其他的乱连。
考虑求\(h\):
假设有\(n\)个度数为\(1\),\(m\)个度数为\(2\)的点。首先是\((n+m*2)!\)枚举每条边往哪里连,这样显然为算重。首先度数为\(2\)的点交换两条出边后仍是同种方案,所以先乘上\(\frac{1}{2^m}\);交换两条入边也是相同的方案,所以在再乘上\(\frac{1}{2^m}\)就好了吗?不是的,因为如果某个点的两个入边是相同的点连过来的(也就是连出重边),那么就不能交换了。
设\(G_i\)表示至少有\(i\)个点连出重边,不考虑交换同一个点的两条入边的方案数,则:
\]
设\(F_i\)表示恰好\(i\)个点连出重边,不考虑交换同一个点的两条入边的方案数,则:
\]
然后:
\]
但是注意到,直接这么算是\(O(N^4)\)的(枚举\(n,m\),然后容斥算\(F\)又是\(O(N^2)\))。于是我们考虑将\(h\)写成:
\]
就是考虑每个\(G\)被计算的系数:
\]
这个就是带入求\(F\)的容斥式子就可以推出来。
\(\\\)
于是就做完了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 505
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
int n,mod;
ll fac[N<<1],ifac[N<<1];
ll C[N][N],A[N][N];
ll pw[N<<1],pw2[N<<1];
ll inv2;
int cal(int i,int i1) {
if(i1==0) return 1;
else if(i1==1) return i;
else return i*(i-1)/2;
}
ll sum[N];
ll coef[N];
void pre(int n) {
fac[0]=1;
for(int i=1;i<=2*n;i++) fac[i]=fac[i-1]*i%mod;
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++)
C[i][j]=(!j||i==j)?1:(C[i-1][j-1]+C[i-1][j])%mod;
for(int i=0;i<=n;i++) {
A[i][0]=1;
for(int j=1;j<=i;j++) A[i][j]=A[i][j-1]*(i-j+1)%mod;
}
inv2=mod+1>>1;
pw[0]=pw2[0]=1;
for(int i=1;i<=n;i++) {
pw[i]=pw[i-1]*inv2%mod;
pw2[i]=pw2[i-1]*2%mod;
}
for(int i=0;i<=n;i++) {
for(int j=0;j<=i;j++) {
if(i-j&1) {
(coef[i]+=mod-pw2[j]*C[i][j]%mod+mod)%=mod;
} else {
(coef[i]+=pw2[j]*C[i][j]%mod)%=mod;
}
}
}
}
//h: 乱连
ll h[N][N];
//g: 无自环
ll g[N][N];
//f:
ll f[2][N][N];
ll cal_h(int n,int m) {
static ll tem[N<<1],ans;
for(int i=0;i<=m;i++) tem[i]=0;
ans=0;
for(int i=0;i<=m;i++) tem[i]=C[m][i]*A[m][i]%mod*fac[n+(m-i)*2]%mod*pw[m-i]%mod;
for(int i=0;i<=m;i++) (ans+=tem[i]*coef[i])%=mod;
return ans*pw[m]%mod;
}
ll Ans[N];
int main() {
int type=Get();
n=Get(),mod=Get();
pre(n);
if(n==1) {cout<<0;return 0;}
for(int a=0;a<=n;a++)
for(int b=0;b<=n-a;b++)
h[a][b]=cal_h(a,b);
for(int i=0;i<=n;i++) g[0][i]=h[0][i];
for(int i=1;i<=n;i++) {
for(int j=0;j<=n-i;j++) {
g[i][j]=h[0][i+j];
for(int k=1;k<=i;k++) {
if(k&1) {
g[i][j]=(g[i][j]-C[i][k]*h[k][i+j-k])%mod;
if(g[i][j]<0) g[i][j]+=mod;
} else {
g[i][j]=(g[i][j]+C[i][k]*h[k][i+j-k])%mod;
}
}
if(g[i][j]<0) g[i][j]+=mod;
else if(g[i][j]>=mod) g[i][j]-=mod;
}
}
f[0][0][0]=1;
for(int i=0;i<n;i++) {
int now=i&1;
memset(f[now^1],0,sizeof(f[now^1]));
for(int j=0;j<=i;j++) {
for(int k=0;k<=j;k++) {
if(!f[now][j][k]) continue ;
(f[now^1][j+1][k+1]+=f[now][j][k]);
int a=k,b=j-k,c=j-k;
if(b) (f[now^1][j][k]+=f[now][j][k]*b);
if(k) (f[now^1][j][k-1]+=f[now][j][k]*k);
if(c) (f[now^1][j][k]+=f[now][j][k]*c);
if(k) (f[now^1][j][k-1]+=f[now][j][k]*k);
if(k) (f[now^1][j-1][k-1]+=f[now][j][k]*k);
if(k>1) (f[now^1][j-1][k-2]+=f[now][j][k]*k*(k-1));
if(k&&b) (f[now^1][j-1][k-1]+=f[now][j][k]*k*b);
if(k&&c) (f[now^1][j-1][k-1]+=f[now][j][k]*k*c);
if(b&&c) (f[now^1][j-1][k]+=f[now][j][k]*b*c);
}
}
for(int j=0;j<=i+1;j++)
for(int k=0;k<=j;k++)
if(f[now^1][j][k]) f[now^1][j][k]%=mod;
}
int now=n&1;
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++) {
(Ans[n-i]+=g[j][i-j]*f[now][i][j])%=mod;
}
for(int i=n;i>=0;i--)
for(int j=i+1;j<=n;j++)
Ans[i]=(Ans[i]-Ans[j]*C[j][i]%mod+mod)%mod;
cout<<Ans[0];
return 0;
}
【JSWC2019】 小X的咒语的更多相关文章
- 【BZOJ5073】[Lydsy十月月赛]小A的咒语 DP(错解)
[BZOJ5073][Lydsy十月月赛]小A的咒语 题解:沙茶DP,完全不用后缀数组. 用f[i][j]表示用了A的前i个字符,用了j段,最远能匹配到哪.因为显然我们能匹配到的地方越远越好,所以我们 ...
- 5073 [Lydsy1710月赛]小A的咒语
LINK:[Lydsy1710月赛]小A的咒语 每次给定两个串 要求从a串中选出x段拼成B串 能否做到.T组数据. \(n\leq 100000,m\leq 100000,T\leq 10,x\leq ...
- 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp
题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...
- BZOJ5073 小A的咒语(动态规划)
设f[i][j][0/1]为前i位选j段时其中第i位选/不选最多能匹配到哪,转移时f[i][j][0]→f[i+1][j][0],f[i][j][1]→f[i+1][j][0],f[i][j][1]→ ...
- [BZOJ5073][Lydsy1710月赛]小A的咒语
bzoj description 你有一个\(A\)串和\(B\)串,你需要判断是否可以在\(A\)串中拆出\(x\)个互不相交的子串,使它们按顺序拼在一起可以组成\(B\)串. \(|A|,|B|\ ...
- [BZOJ5073] [Lydsy1710月赛]小A的咒语 后缀数组+dp+贪心
题目链接 首先这种题一看就是dp. 设\(dp[i][j]\)表示\(A\)序列中到\(i\)位之前,取了\(j\)段,在\(B\)中的最长的长度. 转移也比较简单 \[ dp[i][j] \to d ...
- 17.10.28&29
28上午 骚猪选讲 28下午 BOZJ 1081 [SCOI2005]超级格雷码 感觉就是一个找规律,然后模拟输出.半天没找到一个比较简便的模拟方法,这份代码是学习网上一位大佬的,很巧妙. 代码: # ...
- 【ZJ选讲·BZOJ 5073】
小A的咒语 给出两个字符串A,B (len<=105) 现在可以把A串拆为任意段,然后取出不超过 x 段,按在A串中的前后顺序拼接起来 问是否可以拼出B串. [题解] ①如果遇 ...
- 【小程序分享篇 二 】web在线踢人小程序,维持用户只能在一个台电脑持登录状态
最近离职了, 突然记起来还一个小功能没做, 想想也挺简单,留下代码和思路给同事做个参考. 换工作心里挺忐忑, 对未来也充满了憧憬与担忧.(虽然已是老人, 换了N次工作了,但每次心里都和忐忑). 写写代 ...
随机推荐
- Scrapy 运行多个爬虫
本文所使用的 Scrapy 版本:Scrapy==1.8.0 一个 Scrapy 项目下可能会有多个爬虫,本文陈述两种情况: 多个爬虫 所有爬虫 显然,这两种情况并不一定是等同的.假设当前项目下有 3 ...
- wordpress 数据查询-全局注入-模板数据消费输出简图
我一直比较好奇,类似于wordpress这样的CMS,它可以做的很灵活,同样的软件,为什么就能做出几乎完全不具有相似性的不同站点来呢?除了功能可以有大不同以外,即便是相同的简单blog站他们的外观也可 ...
- var变量
# Aduthor:CCIP-Ma name = "ma" name2 = name name = "ccip-ma" print("My name ...
- PHP 日历函数手册
PHP日历函数安装>>> 函数名称 描述 cal_days_in_month 返回某个历法中某年中某月的天数 cal_from_jd 转换Julian Day计数到一个支持的历法. ...
- win10笔记本电脑连wifi显示“无internet,安全”解决办法
吹一波, 不出意外的话,这应该是网上最全最详细的解决办法......毕竟妹子的电脑遇到了问题,咱一定要给她解决啊. 问题描述:连上了WiFi,显示“无Internet,安全”.但实际上她的电脑是有网的 ...
- swift开发之--简单封装Alamofire请求类以及简单使用SnapKit
以前在swift3的时候,写过类似的,那个时候还没有很成熟的网络请求类库,在这里,还是衷心感谢大神们的付出! 具体效果如下,先上图: 点击按钮的时候,请求数据,数据结构如下: { ; reason = ...
- MySQL循环日期
DROP PROCEDURE IF EXISTS `insertManyDate`$$ CREATE DEFINER=`root`@`%` PROCEDURE `insertManyDate`(IN ...
- nginx发布静态资源
nginx发布静态资源 参考 ngx_http_index_module index指令 ngx_http_core_module http指令 location指令 listen指令 root指令 ...
- jenkins+maven+svn 持续集成环境搭建
说明:部署传统的web应用(.war) 准备工作: (1) 系统环境:CentOS7 (2) 安装JDK:https://www.cnblogs.com/myitnews/p/11493847.htm ...
- 生鲜超市项目错误及解决办法(crispy_forms、外键指向自己、class嵌套访问父类、meta类及各种字段参数)
为什么要在INSTALLED_APPS中加入crispy_forms? 因为django-crispy-forms 是对django form在html页面呈现方式进行管理的一个第三方插件. 为什么有 ...