题解-Atcoder_agc005D ~K Perm Counting
Problem
题意概要:给出\(n,k\),求合法的排列个数,其中合法定义为任何数字所在位置与自身值差的绝对值不为\(k\)(即求排列\(\{A_i\}\),使得\(\forall i\in[1,n],|a_i-i|\not =k\)
Solution
刚看这道题时除了全集取反搞容斥外没有任何思路啊
\(f_i\)表示排列中至少有\(i\)对冲突的方案数,一对冲突定义为存在一个\(i\)使得\(|a_i-i|=k\)
考虑全集取反,加上一点点容斥思想可得
\]
至于怎么得到 \(f_i\),就是这道题难点所在,关键思路是画图
构建一个二分图:
- 其中 \(i\) 为数值 \(i\),\(i'\) 为 \(i\) 在排列中的位置编号
- 构建边为冲突,即所有 \(i'\) 要和 \(i\pm k\) 连边
就像这样(模拟 \(n=4,k=1\) 的情况):

发现这个二分图中其实只有\(2k\)条链,于是可以对这\(2k\)条链进行Dp
在某条链上:设\(g[i][j][0/1]\)表示考虑前\(i\)个点,且已经有\(j\)对冲突,\(i\)号与\(i+1\)号连与不连的方案数,得出转移方程:
\]
对于每条链的\(f[i]\)即为\(g[end][i][0]+g[end][i][1]\)(\(end\)为链的末尾),最后合并\(2k\)条链的时候可以玩背包
但实际上有个小技巧,就是将\(2k\)条链首尾顺次相接,在两条链的交界处不转移第二个方程即可
Code
#include <cstdio>
const int N=2040,p=924844033;
int f[N+N][N][2];
bool end[N+N];
int n,k,Ans,fac[N];
inline int qm(int x){return x<p?x:x-p;}
int main(){
scanf("%d%d",&n,&k);fac[0]=1;
for(int i=1;i<=n;++i)fac[i]=1ll*fac[i-1]*i%p;
for(int i=1,tt=0,d;i<=k;++i){
d=(n-i)/k+1;
tt+=d,end[tt]=true;
tt+=d,end[tt]=true;
}
f[1][0][0]=1;
for(int i=1;i<=n+n;++i)
for(int j=0;j<=n;++j){
f[i+1][j][0]=qm(f[i][j][0]+f[i][j][1]);
if(!end[i])f[i+1][j+1][1]=f[i][j][0];
}
for(int i=0,t;i<=n;++i){
t=1ll*fac[n-i]*qm(f[n+n][i][0]+f[n+n][i][1])%p;
if(i&1)Ans=qm(Ans-t+p);
else Ans=qm(Ans+t);
}
printf("%d\n",Ans);
return 0;
}
题解-Atcoder_agc005D ~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_ ...
- 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$意义下相同的数之间才会出现不满足条件的情况,而且仅出现在相邻的情况 那么我们考虑把这个性质利用起来 我 ...
- [AT2062] ~K Perm Counting
AT2602 , Luogu 求对于 \(n\) 个数的排列 , 有多少种方案满足对于所有的 \(i\) , \(|P_i - i| != K\) , 答案对 \(924844033\) 取模 . \ ...
- 【agc005d】~K Perm Counting
题目大意 求有多少中1~n的排列,使得\(abs(第i个位置的值-i)!=k\) 解题思路 考虑容斥,\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]表示至少有i个位 ...
- 【题解】K乘积
题目描述 有N个数,每个数的范围是[-50,50],现在你要从这N个数中选出K个,使得这K个数的乘积最大. 输入格式 第一行,N和K. 1 <= N <= 50. 1 <= K & ...
- 题解——UVA11997 K Smallest Sums
题面 背景 输入 输出 翻译(渣自翻) 给定K个包含K个数字的表,要求将其能产生的\( k^{k} \)个值中最小的K个输出出来 题解 k路归并问题的经典问题 可以转化为二路归并问题求解 考虑A[], ...
- 题解 P3605 [USACO17JAN]Promotion Counting P
分块\(yyds\) ----关于线段树合并的题我用分块过掉这件事 题目传送门 先说正解 正解当然是线段树合并等一类做法了 至于解析...出门右转题解区第一篇 (就是他让我看不懂,然后用分块打的\(Q ...
随机推荐
- Spring Boot笔记二:快速创建以及yml文件自动注入
上个笔记写了如何自己去创建Spring boot,以及如何去打jar包,其实,还是有些麻烦的,我们还自己新建了几个文件夹不是. Idea可以让我们快速的去创建Spring boot应用,来看 一.快速 ...
- laravel 5.4 fopen(): Filename cannot be empty
1.出错的报错信息(我在用laravel5.4文件上传时候出错的) laravel 5.4 fopen(): Filename cannot be empty 2.解决的方法 在php.ini中修改临 ...
- Markdown Cheatsheet
This is intended as a quick reference and showcase. For more complete info, see John Gruber's origin ...
- 905. Sort Array By Parity
Description Given an array A of non-negative integers, return an array consisting of all the even el ...
- JS创建对象之构造函数模式
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = f ...
- linux下安装好mysql后,登录时提示libgcc_s.so.1 must be installed for pthread_cancel to work
网上找了很多帖子,各说纷纭, 自己到https://centos.pkgs.org/下载对应版本的libgcc_s.so.1,使用rpm -ivh libgcc-4.8.5-16.el7.i686.r ...
- Spring IoC 依赖注入的方法大全 XML配置方式
Spring 依赖注入 构造方法注入 ① 根据索引注入 <bean name="student" class="cn.bdqn.SpringDI.Student ...
- HTTP访问控制(CORS)
当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求. 比如,站点 http://domain-a.com 的某 HTML 页面通过 <img ...
- python3.x与2.x区别
1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可 以取得很好的优化结果. Py3.1性能比Py2 ...
- 【全文转载】Gradle、Maven项目相互转换
Doublemine 首页 标签 归档 关于 搜索 Gradle.Maven项目相互转换 发表于 2017-08-21 | 更新于: 2018-03-18 | 阅读次数: 920 字数统计 ...