AGC 005D.~K Perm Counting(容斥 DP 二分图)

题目链接

\(Description\)

给定\(n,k\),求 满足对于所有\(i\),\(|a_i-i|\neq k\)的排列的个数。
\(2\leq n\leq 2000,\quad 1\leq k\leq n-1\)。

\(Solution\)

容斥。则\(Ans=\sum_{i=0}^n(-1)^ig(i)(n-i)!\),其中\(g(i)\)为至少有\(i\)个位置满足\(|a_i-i|=k\)的排列数。

考虑如何计算\(g(x)\)。每个\(i\)向\(i+k\)和\(i-k\)连边,可以得到一张二分图,\(g(x)\)就是在这张二分图上选\(x\)个匹配的方案数。

我们还可以发现,图中的匹配形成了\(2k\)条互不相交的链,且每条链上的数模\(k\)相同(也就是模\(k\)不同的数是互不影响的,所以枚举模数就可以得到所有链了)。

如果只有一条长\(l\)的链,那么就是对\(l-1\)个点DP,\(f[i][j][0/1]\)表示当前第\(i\)个点,已经选了\(j\)个匹配,这个点选不选(这个点选要求上一个点没选)。
对于\(2k\)条链也是一样的,只要在链之间加一个点,并强制它不能选(\(f[i][j][1]=0\)),就可以把这些链合在一起DP啦。

这样复杂度\(O(n^2)\),然而好多dalao用NTT\(n\log n\)过掉了orz。



因为想跑快点(个人习惯)写的有点乱,代码也可以看他的:http://www.cnblogs.com/wxjor/p/9476998.html

//20ms  256KB
#include <cstdio>
#include <algorithm>
#define mod 924844033
typedef long long LL;
const int N=4005;//2n

int ban[N],f[2][N][2],fac[N];

int main()
{
    int n,K,cnt=0; scanf("%d%d",&n,&K);
    for(int i=1; i<=K; ++i)
    {
        ban[++cnt]=1;
        for(int j=i+K; j<=n; j+=K) ban[++cnt]=0;
        ban[++cnt]=1;//就是两条链啊
        for(int j=i+K; j<=n; j+=K) ban[++cnt]=0;
    }
    int p=0; f[p][0][0]=1;
    for(int i=0; i<cnt; ++i,p^=1)
        for(int j=0; j<=i; ++j)
        {
            f[p^1][j][0]=(f[p][j][0]+f[p][j][1])%mod;
            if(!ban[i+1]) f[p^1][j+1][1]=f[p][j][0];
            f[p][j][0]=f[p][j][1]=0;
        }
    fac[0]=1;
    for(int i=1; i<=n; ++i) fac[i]=1ll*fac[i-1]*i%mod;
    LL ans=0;
    for(int i=0; i<=n; ++i)
        ans+=i&1?mod-1ll*fac[n-i]*(f[p][i][0]+f[p][i][1])%mod:1ll*fac[n-i]*(f[p][i][0]+f[p][i][1])%mod;
    printf("%lld\n",ans%mod);

    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/10095512.html

时间: 2024-09-30 06:26:28

AGC 005D.~K Perm Counting(容斥 DP 二分图)的相关文章

$bzoj2560$ 串珠子 容斥+$dp$

正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多少种方案可以连成一张联通图 显然考虑容斥呗?设$f_i$表示状态为$i$的点连成联通图的合法方案,$g_i$表示状态为$i$的点随便连边的所有方案 显然$g_i$可以先预处理出来?就等于$\prod_{u,v\in i}a_{u,v}$.然后$f_i$就等于$g_i$减去不合法的数量.不合法数量显然

[BZOJ4455][ZJOI2016]数星星(容斥DP)

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 707  Solved: 419[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这

【XSY3156】简单计数II 容斥 DP

题目大意 定义一个序列的权值为:把所有相邻的相同的数合并为一个集合后,所有集合的大小的乘积. 特别的,第一个数和最后一个数是相邻的. 现在你有 \(n\) 种数,第 \(i\) 种有 \(c_i\) 个.求所有不同的序列的权值的和. \(n\leq 50,c_i\leq 100\) 题解 考虑第一个数和最后一个数不相邻时怎么做. 记 \(g_{i,j}\) 为出现了 \(i\) 次的数分成 \(j\) 个集合,所有集合大小的乘积的和. \[ g_{i,j}=\sum_{k=1}^ig_{i-k,

题解-Atcoder_agc005D ~K Perm Counting

Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\(\forall i\in[1,n],|a_i-i|\not =k\) Solution 刚看这道题时除了全集取反搞容斥外没有任何思路啊 \(f_i\)表示排列中至少有\(i\)对冲突的方案数,一对冲突定义为存在一个\(i\)使得\(|a_i-i|=k\) 考虑全集取反,加上一点点容斥思想可得 \[A

【agc005d】~K Perm Counting

题目大意 求有多少中1~n的排列,使得\(abs(第i个位置的值-i)!=k\) 解题思路 考虑容斥,\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]表示至少有i个位置是不合法的方案数)\) 考虑如何求g[i] 将每个位置和每个值都作为一个点,有2n个点,如果第i位置不可以填j,将位置i向值j连边. 这样,就得到了一个二分图,问题就变成了选i条边的方案数. 将二分图的每条链拉出来,并在一起,就形成2n个点排成一排,一些相邻点之间有边. 设\(f[i][j][0/

hdu4624 Endless Spin (min-max容斥+dp)

min-max容斥: $$max\{a_i\}=\sum\limits_{S}(-1)^{|s|-1}min\{a_i|a_i \in S\}$$ 关于证明,可以把一个数$a$看作是集合$\{1...a\}$,于是max相当于取并集,min相当于取交集,就变成了普通的容斥 然后这道题就可以dp了 然而我一直被卡精度 以下代码大概是对的( 1 #include<bits/stdc++.h> 2 #include<tr1/unordered_map> 3 #define CLR(a,x

bzoj2655calc 容斥+dp

2655: calc Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 322  Solved: 197[Submit][Status][Discuss] Description 一个序列a1,...,an是合法的,当且仅当: 长度为给定的n. a1,...,an都是[1,A]中的整数. a1,...,an互不相等. 一个序列的值定义为它里面所有数的乘积,即a1a2...an. 求所有不同合法序列的值的和. 两个序列不同当且仅当他们任意一位不一样.

Jzzhu and Numbers CodeForces - 449D (容斥,dp)

大意: 给定集合a, 求a的按位与和等于0的非空子集数. 为了方便表述, 把每个数看成一个二进制位表示的集合, 例如十进制的$10$就看做集合$\{1,3\}$. 假设给定数的范围在$[0,2^{m})$内, 记$U=\{0,1,2,\cdots,m-1\}$. 首先根据容斥可以得到 $$ans=\sum\limits_{S\subseteq 2^{U}}(-1)^{|S|}(2^{f_S}-1) \tag{1}$$ 其中$f_S=\sum\limits_{T\in a}[T\supseteq

4455[Zjoi2016]小星星 容斥+dp

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 527  Solved: 317[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这