AT2602 , Luogu

求对于 \(n\) 个数的排列 , 有多少种方案满足对于所有的 \(i\) , \(|P_i - i| != K\) , 答案对 \(924844033\) 取模 .

\(n,K \le 2000\)

设 \(g[i]\) 表示至少有 \(i\) 个数不满足题意的方案数 , 则 \(ans = \sum_{i=0}^n (-1)^{i} g[i]\) .

可以画一个二分图 , 左边表示下标 , 右边表示取值 , 相隔 \(K\) 格的左右连一条边 . 网上有一个图 :

对于每一条链 , 每个点只能连一条边 . 所以在每一条链上有转移 : 设 \(f[i][j][0/1]\) 表示选到第 \(i\) 个数 , 已经连了 \(j\) 条边 , \(i\) 与 \(i-1\) 是否连边的方案数 , 在链的内部转移 .

对于所有的链 , 可以拼接在一起 , 链之间也可以转移 \(f[i][j][0]\) 的方案数 , 这就相当于继承之前的结果继续 \(DP\) .

要特别注意的是 , 拼接的链的长度是 \(2n\) .

时间复杂度 \(O((2n)^2)\)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cassert>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
register LL x=0,f=1;register char c=getchar();
while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f*x;
} const int N = 4005;
const int mod = 924844033; int a[N], g[N], f[N][N][2], fac[N];
int n, K, cnt, ans; inline int add(int x, int y){return (x+y)%mod;}
inline int dec(int x, int y){return (x-y+mod)%mod;}
inline int mul(LL x, int y){return x*y%mod;} int main(){
n = read(), K = read();
fac[0] = fac[1] = 1;
for(int i = 2; i <= n; ++i) fac[i] = mul(fac[i-1], i);
for(int i = 1; i <= K; ++i){
for(int j = i; j <= n; j += K)
a[++cnt] = j;
for(int j = i; j <= n; j += K)
a[++cnt] = j;
}
assert(cnt == (n << 1));
f[1][0][0] = 1;
for(int i = 2; i <= (n << 1); ++i){
for(int j = 0; j <= min(n, i/2); ++j){
f[i][j][0] = add(f[i-1][j][0], f[i-1][j][1]);
if(j > 0 && a[i] - a[i-1] == K) f[i][j][1] = f[i-1][j-1][0];
}
}
for(int i = 0; i <= n; ++i){
g[i] = add(f[n << 1][i][0], f[n << 1][i][1]);
if(!(i&1)) ans = add(ans, mul(g[i], fac[n - i]));
else ans = dec(ans, mul(g[i], fac[n - i]));
}
printf("%d\n", ans);
}

\(CF\) 上还有一篇讨论 , 是这题的 \(NTT\) 做法 : Solve AGC005D with NTT

[AT2062] ~K Perm Counting的更多相关文章

  1. [Agc005D]K Perm Counting

    [Agc005D] K Perm Counting Description 糟糕爷特别喜爱排列.他正在构造一个长度为N的排列.但是他特别讨厌正整数K.因此他认为一个排列很糟糕,当且仅当存在至少一个i( ...

  2. AGC 005 D - ~K Perm Counting

    D - ~K Perm Counting 链接 题意: 求有多少排列对于每个位置i都满足$|ai−i|!=k$.n<=2000 分析: 容斥+dp. $answer = \sum\limits_ ...

  3. 题解-Atcoder_agc005D ~K Perm Counting

    Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\( ...

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

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

  5. [AGC005D] ~K Perm Counting [dp]

    题面 传送门 思路 首先可以明确的一点是,本题中出现不满足条件的所有的数,都是分组的 只有模$K$意义下相同的数之间才会出现不满足条件的情况,而且仅出现在相邻的情况 那么我们考虑把这个性质利用起来 我 ...

  6. 【agc005d】~K Perm Counting

    题目大意 求有多少中1~n的排列,使得\(abs(第i个位置的值-i)!=k\) 解题思路 考虑容斥,\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]表示至少有i个位 ...

  7. 一句话题解&&总结

    CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...

  8. 做题记录 To 2019.2.13

    2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...

  9. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...

随机推荐

  1. mouseleave([[data],fn])

    mouseleave([[data],fn]) 概述 当鼠标指针离开元素时,会发生 mouseleave 事件.该事件大多数时候会与mouseenter 事件一起使用. 与 mouseout 事件不同 ...

  2. 五十六. playbook基础 、 playbook进阶

    1.playbook练习 安装Apache并修改监听端口为8080 修改ServerName配置,执行apachectl -t命令不报错 设置默认主页hello world 启动服务并设开机自启   ...

  3. MVC的一些有用代码

    1.将patial view转成字符串 protected string RenderPartialViewToString(string viewName, object model) { if ( ...

  4. 牛客练习赛53 (C 富豪凯匹配串) bitset

    没想到直接拿 bitset 能过 $10^8$~ code: #include <bits/stdc++.h> #define N 1004 #define setIO(s) freope ...

  5. [Luogu] 贪婪大陆

    https://www.luogu.org/problemnew/show/P2184 区间修改时只需修改区间端点的numl或numr值 区间查询x-y只需用1-y的numr - 1-(x - 1)的 ...

  6. Codeforces Educational Codeforces Round 67

    目录 Contest Info Solutions A. Stickers and Toys B. Letters Shop C. Vasya And Array D. Subarray Sortin ...

  7. 删除git中无用的大文件

    推荐阅读:为什么你的 Git 仓库变得如此臃肿 有时候我们不小心提交了一些大文件上去,后来删除了,但是已经于事无补了,整个git的提及已经蹭蹭上去了. 这个时候怎么办呢? 1. 查看有哪些大文件(to ...

  8. java试题复盘——9月8日

    上: 1.可将语句块或方法设为同步使用的语句是(A) A synchronized              用于方法或者代码块前,使此方法或者代码变成同步的 B static             ...

  9. poj 1458 Common Subsequence ——(LCS)

    虽然以前可能接触过最长公共子序列,但是正规的写应该还是第一次吧. 直接贴代码就好了吧: #include <stdio.h> #include <algorithm> #inc ...

  10. 一文教你读懂Python中的异常信息

    正文共:11813 字 2 图 预计阅读时间: 30 分钟 原文:https://realpython.com/python-traceback/ 译者:陈祥安 原文有所改动. 在写 Python 代 ...