[AT2062] ~K Perm Counting
求对于 \(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的更多相关文章
- [Agc005D]K Perm Counting
[Agc005D] K Perm Counting Description 糟糕爷特别喜爱排列.他正在构造一个长度为N的排列.但是他特别讨厌正整数K.因此他认为一个排列很糟糕,当且仅当存在至少一个i( ...
- AGC 005 D - ~K Perm Counting
D - ~K Perm Counting 链接 题意: 求有多少排列对于每个位置i都满足$|ai−i|!=k$.n<=2000 分析: 容斥+dp. $answer = \sum\limits_ ...
- 题解-Atcoder_agc005D ~K Perm Counting
Problem AtCoder-agc005D 题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\( ...
- AGC 005D.~K Perm Counting(容斥 DP 二分图)
题目链接 \(Description\) 给定\(n,k\),求 满足对于所有\(i\),\(|a_i-i|\neq k\)的排列的个数. \(2\leq n\leq 2000,\quad 1\leq ...
- [AGC005D] ~K Perm Counting [dp]
题面 传送门 思路 首先可以明确的一点是,本题中出现不满足条件的所有的数,都是分组的 只有模$K$意义下相同的数之间才会出现不满足条件的情况,而且仅出现在相邻的情况 那么我们考虑把这个性质利用起来 我 ...
- 【agc005d】~K Perm Counting
题目大意 求有多少中1~n的排列,使得\(abs(第i个位置的值-i)!=k\) 解题思路 考虑容斥,\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]表示至少有i个位 ...
- 一句话题解&&总结
CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...
- 做题记录 To 2019.2.13
2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...
- AtCoder Grand Contest 005
AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...
随机推荐
- MySQL 5.6 中一个重要的优化——Index Condition Pushdown,究竟push down了什么
1 问题描述 一条SQL,在数据库中是如何执行的呢?相信很多人都会对这个问题比较感兴趣.当然,要完整描述一条SQL在数据库中的生命周期,这是一个非常巨大的问题,涵盖了SQL的词法解析.语 ...
- Self install windows service in .NET c#
http://stackoverflow.com/questions/4144019/self-install-windows-service-in-net-c-sharp using System; ...
- E.Substring Reverse Gym - 101755E
Substring Reverse Problem Two strings s and t of the same length are given. Determine whether it is ...
- 1626:【例 2】Hankson 的趣味题
1626:[例 2]Hankson 的趣味题题解 [题目描述] Hanks 博士是 BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson ...
- BZOJ 4734 UOJ #269 如何优雅地求和 (多项式)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=4734 (UOJ) http://uoj.ac/problem/269 题解 ...
- 【ElasticSearch+NetCore 第二篇】Nest封装
using Elasticsearch.Net; using Nest; using System; using System.Collections.Generic; using System.Li ...
- jinja2-过滤器
过滤器 过滤器是个函数,参数就是管道(pipe)前面那个变量.比如 123|myfilter,123就是myFilter的参数.如果需要两个参数,则在myFilter后面加(),即123|myFil ...
- Python实现进度条的效果
from itertools import cycle from time import sleep for frame in cycle(r'-\|/-\|/'): print('\r', fram ...
- 添加sql距离现在多久以前时间条件
UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(add_time)<=25200 其中now()是现在时间 add_time是其他时间点 25200:是秒,现在和ad ...
- 使用pycharm发布python程序到ubuntu中运行
前提条件: 1.ubuntu安装了vsftpd,可以参考:https://www.cnblogs.com/xienb/p/9322805.html 2.安装专业版pycharm 步骤: 1.新建一个P ...