CF1909I Short Permutation Problem

news/2025/10/28 20:40:34/文章来源:https://www.cnblogs.com/SmpaelFx/p/19154612

CF1909I Short Permutation Problem


并非独立切,大量参考题解。

对于排列计数问题,考虑三个方向:容斥、连续段DP、按顺序加数。

发现容斥和连续段DP没前途,考虑按顺序加数。从 \(1\) ~ \(n\) 加数显然是不行的,因为我们不知道加入的数是否会产生贡献/撤销贡献。考虑按一个合适的顺序加数,使得总能知道贡献是多少。我们希望加入 \(i\) 时只加入 \(<m-i\) 的数或 \(\ge m-i\) 的数。于是,对于 \(m\) 为偶数,考虑按顺序加入 \(\frac{m}{2},\frac{m}{2}-1,\frac{m}{2}+1,\frac{m}{2}-2,\frac{m}{2}+2,\dots\)。对于 \(m\) 为奇数,考虑按顺序加入 \(\lfloor\frac{m}{2}\rfloor,\lfloor\frac{m}{2}\rfloor+1,\lfloor\frac{m}{2}\rfloor-1,\lfloor\frac{m}{2}\rfloor+2,\lfloor\frac{m}{2}\rfloor-2,\dots\)

接下来不妨只考虑 \(m\) 为偶数的情况,奇数是类似的。发现加数过程可以分为两部分:

  1. \(\frac{m}{2}\) 两侧均还有数待加入。
  2. 待加入全部 \(>\frac{m}{2}\)

第 1 部分我们发现在 \(m\) 增加的过程中,每次多转移两轮,可以直接维护;第 2 部分我们推式子转为卷积。

第 1 部分

\(p\) 为加数的序列,\(f_{i,j}\) 表示加入了前 \(i\) 个数,有 \(j\) 对产生了贡献。

若加入一个能产生贡献的数(\(>\frac{m}{2}\)),转移为:

  1. \(f_{i+1,j+1}\leftarrow (j+2)f_{i,j}\)(加在以产生贡献的缝隙或边界)
  2. \(f_{i+1,j+2}\leftarrow (i-j-1)f_{i,j}\)(加在不产生贡献的缝隙中)

若加入一个不能产生贡献的数,转移为:

  1. \(f_{i+1,j-1}\leftarrow j\cdot f_{i,j}\)
  2. \(f_{i+1,j}\leftarrow (i-j+1)f_{i,j}\)

第 2 部分

设 DP 终止在 \(i\),枚举第二维 \(j\)

\(k\) 为有多少个有贡献的缝隙(或边界)插入了数,\(u\) 为有多少个无贡献的缝隙插入了数。

\[ans_{j+n-i+u}\leftarrow f_{i,j}(n-i)!\binom{n-i-1}{k+u-1}\binom{j+2}{k}\binom{i-j-1}{u} \]

注意到 \(\binom{j+2}{k}=\binom{j+2}{j-k+2}\)(这里是因为我们想消掉 \(k\),现在是差卷积,考虑转为和卷积)。

范德蒙德卷积:\(\sum\limits_k\binom{n-i-1}{k+u-1}\binom{j+2}{j-k+2}=\binom{n-i+j+1}{j+u+1}\)\(k\) 的范围在组合数中自动保证,所以不会对正确性产生影响)。

现在有

\[ans_{j+n-i+u}\leftarrow f_{i,j}(n-i)!\binom{n-i+j+1}{j+u+1}\binom{i-j-1}{u} \]

\(i\) 是常数\(j,u\)是变量,转移只与 \(j\)\(u\)\(j+u\) 有关。

考虑写成卷积

\[F(x)=\sum\limits_{j}f_{i,j}(i-j-1)! \]

\[G(x)=\sum\limits_{u}\frac{1}{(n-i-u)!u!} \]

\[ans_{n-i+t}=\frac{(n-i)!}{(t+1)!(i-t-1)!}[x^t]F(x)G(x) \]

做完了。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
template<typename T>
void chkmin(T &x,const T &y){x=min(x,y);}
template<typename T>
void chkmax(T &x,const T &y){x=max(x,y);}
const int inf=0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353,G=3,MOD2=1000000007;
void add(int &x,int y,int p=MOD){x+=y;if(x>=p) x-=p;
}
int qpow(int a,ll b,int p=MOD){int mul=1;while(b){if(b&1) mul=(ll)mul*a%p;a=(ll)a*a%p;b>>=1;}return mul;
}
const int N=4005;
int n,x,fact[N],invfact[N],dp[N],ans;
void trans1(int &i){for(int j=i-1;j>=0;j--){add(dp[j+1],(ll)(j+2)*dp[j]%MOD),add(dp[j+2],(ll)(i-j-1)*dp[j]%MOD);dp[j]=0;}i++;
}
void trans2(int &i){for(int j=0;j<i;j++){if(j) add(dp[j-1],(ll)j*dp[j]%MOD);dp[j]=(ll)(i-j+1)*dp[j]%MOD;}i++;
}
void ntt(vector<int> &f,int flag=0){int n=f.size();vector<int> rev(n);for(int i=1;i<n;i++){rev[i]=rev[i>>1]>>1;if(i&1) rev[i]|=(n>>1);}for(int i=1;i<n;i++) if(rev[i]<i) swap(f[rev[i]],f[i]);for(int w=1;w<n;w<<=1){int step=qpow(G,(MOD-1)/(w<<1));if(flag) step=qpow(step,MOD-2);for(int i=0;i<n;i+=(w<<1)){int cur=1;for(int j=i;j<i+w;j++,cur=(ll)cur*step%MOD){int a=f[j],b=(ll)cur*f[j+w]%MOD;f[j]=(a+b)%MOD;f[j+w]=(a-b+MOD)%MOD;}}}if(flag){int inv=qpow(n,MOD-2);for(int i=0;i<n;i++) f[i]=(ll)f[i]*inv%MOD;}
}
void mul(vector<int> &f,vector<int> &g){int n=f.size()+g.size()-1,len;for(len=1;len<n;len<<=1);f.resize(len),g.resize(len);ntt(f),ntt(g);for(int i=0;i<len;i++) f[i]=(ll)f[i]*g[i]%MOD;ntt(f,1);
}
void calc(int m){int i=m-2;vector<int> f(i),g(n-i+1);for(int j=0;j<i;j++) f[j]=(ll)dp[j]*fact[n-i+j+1]%MOD*fact[i-j-1]%MOD;for(int j=0;j<=n-i;j++) g[j]=(ll)invfact[n-i-j]*invfact[j]%MOD;mul(f,g);for(int u=0;u<i;u++){int tmp=(ll)f[u]*fact[n-i]%MOD*invfact[u+1]%MOD*invfact[i-u-1]%MOD;add(ans,(ll)tmp*qpow(x,m*n+n-i+u,MOD2)%MOD2,MOD2);}
}
int main(){fact[0]=1;for(int i=1;i<N;i++) fact[i]=(ll)i*fact[i-1]%MOD;invfact[N-1]=qpow(fact[N-1],MOD-2);for(int i=N-1;i>0;i--) invfact[i-1]=(ll)i*invfact[i]%MOD;scanf("%d%d",&n,&x);dp[0]=1;for(int m=4,i=1;m<=n+1;m+=2){if(m>4) trans1(i);trans2(i);calc(m);}memset(dp,0,sizeof(dp));dp[0]=1;for(int m=3,i=1;m<=n+1;m+=2){if(m>3) trans1(i),trans2(i);calc(m);}printf("%d\n",ans);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/949122.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS1 go2 vlp16 局部避障--3 篇 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

25.10.28随笔NOIP模拟赛总结

考试 开考看题,秒了 T1,感觉 T2 是简单 dp,T3 有点神秘不知道,T4 一眼有一个 \(\mathcal O(n^2)\)。于是顺序开题。T1 很快写了,T2 看了一个小时还是不会有点难崩,当时是很快想到一个 dp,设 \(f_{i,j,0/1}\) 表…

第二十八篇

今天是10月28号,上了铁道技术认知。

P8269 [USACO22OPEN] Visits S

P8269 [USACO22OPEN] Visits S 题解题目传送门 博客传送门 首先,每头牛牛都只有一个拜访对象,所以如果考虑图论建模的话,相当于每个点出度都是 1。这相当于图是个基环树森林(注意不只有一棵基环树),而且每个基环…

Luogu P13925 [POKATT 2024] 联合猫国 / The Paw-litical Game 题解 [ 蓝 ] [ 线性 DP ] [ 种类数观察 ]

联合猫国 去年模拟赛做过一道几乎一模一样的题,于是一眼秒了。 本题的一个结论:最终可合并的区间数为 \(\bm{O(n\log n)}\) 级别。 证明可以考虑构造出可合并区间数最多的序列,显然是所有数都相同时的区间数,可以取…

深入解析:【STM32项目开源】基于STM32的独居老人监护系统

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CSP-S 41多校 9

10.28 (虽然但是下发文件NOIP?)10.28 CSP-S 前倒数第二场模拟赛,直接一道都没切出来。。。 再不放信心赛真要没信心了。 t1 dp题。 显然对于每一次行动都是一个背包dp。 变种在于背包更换,更换后容量重新计算。 所…

【25.10.28】模拟赛

T1 code #include<bits/stdc++.h> using namespace std; const int N=5e4+5,M=1e3+5; int n,m,ans=0; char s[N],t[M]; int nxt[M]; int f[N][M]; int g[M][30]; void getnxt(){nxt[1]=0;int j=0;for(int i=2;i&…

CSP-S模拟41

CSP-S模拟41 A. 数轴取物(axis) 显然可以有一个 \(O(n^3)\) 的背包 dp,设 \(dp[i][j][k]\) 表示选区间 \([i,j]\),背包容量为 \(k\) 时可获得的最大价值。每次枚举固定左端点从小到大枚举右端点,发现 \(dp[i][j]\) …

Linux双中文编码笔记

Linux双中文编码笔记/etc/locale.gen zh_CN.GB18030 GB18030zh_CN.GBK GBK 上面两行默认是被注释掉的,要打开。 /usr/sbin/dpkg-reconfigure/usr/sbin不在普通用户的PATH里,再说运行它也需要root权限。 如果dkpg-rec…

C++类和对象(1) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

人工智能之编程基础 Python 入门:第二章 Python 的编辑器 VS Code

人工智能之编程基础 Python 入门:第二章 Python 的编辑器 VS Code人工智能之编程基础 Python 入门 第二章 Python 的编辑器 VS Code@目录人工智能之编程基础 Python 入门前言一、VS Code安装二、配置PythonVS Code 汉…

2019 福建省队集训录

退役前最后的贡献\(\scr{Day}\ 1\) T1 (sort)Source:$\bf{solution}$$\bf{code}$T2 (sort)Source:$\bf{solution}$$\bf{code}$T3 (sort)Source:$\bf{solution}$$\bf{code}$

AIX multibos bootlist

Check bash bootlist -m normal -o hdisk0 blv=hd5 pathid=0 lspv hdisk0 00cc4bc0964f315a rootvg active hdisk1 00cc4bc028d6260c altinst_root…

记录一次nginx能通但是请求一直不了的问题

今天在公司碰到这样一个问题:开发后在测试环境进行部署,部署后有个调用其他部门的接口,需要通过nginx来代理请求转发到另一个部门。运维把nginx配置完成后,本地和开发测试都正常,但是通过测试环境访问一直是不同的…

【嵌入式】PWM DAC的滤波器设计

PWM DAC PWM概念本身很简单,具体可以参考各网上资料。PWM:脉冲宽度调制(英语:Pulse-width modulation,缩写:PWM),简称脉宽调制,是用脉冲来输出模拟信号的一种技术,一般变换后脉冲的周期固定,但脉冲的工作周…

被称作遗憾之物 爬满了脊骨 又把控了痛楚 被称作无用之物 修筑了唯一的通路

test30 前两题都 0pts,nbm(? 2-A 飞船制造 (spaceship.cpp) 怎么有傻子没开 c++11 写了 rank 然后 re 惹 /fad 考虑依次枚举 \(s=i+j+k\),计算出 \(s\) 一定的方案数就能确定唯一的 \(s\),方案数计算好像只能考虑…

neovim在windwos11下snack.nvim的问题

问题复现 首先确定有 find 命令,在执行之后,会出现下面的问题: Command failed: - cmd: `find . -type f -not -path */.git/* -not -path */.*`几乎百分百。 查找原因 查阅之后得知,问题为调用了linux风格的find命…

完整教程:Java 集合 “List + Set”面试清单(含超通俗生活案例与深度理解)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

禁用 IPython 历史记录 history.sqlite

Windows 在 %UserProfile%\.ipython\profile_default\ 文件夹中或 Linux 在 ~/.ipython/profile_default/ 目录中(默认配置文件名为profile_default),新建ipython_config.json文件,填入以下内容即可禁用 IPython 历…