尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

CF1909I Short Permutation Problem

CF1909I Short Permutation Problem
📅 发布时间:2026/6/19 14:54:32

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;
}

相关新闻

  • ROS1 go2 vlp16 局部避障--3 篇 - 教程
  • 25.10.28随笔NOIP模拟赛总结
  • Luogu P13925 [POKATT 2024] 联合猫国 / The Paw-litical Game 题解 [ 蓝 ] [ 线性 DP ] [ 种类数观察 ]

最新新闻

  • 2026伊春放心贵金属回收,CCIC 中检授权收黄金回收铂金回收白银回收持证实体门店 - 中安检金银铂钻回收
  • 天农凤中皇高端滋补鸡选购指南:如何挑选优质滋补禽肉 - 速递信息
  • 鉴源论坛 · 观擎丨DO-178C工具鉴定:从准则分级到操作需求的实战解析
  • Prescan8.5从零安装到MATLAB联调:避坑指南与最佳实践
  • 指纹浏览器行为生物指纹(下):键盘敲击节奏与滚动行为的仿生学建模
  • 大连闲置首饰变现攻略,本地高口碑回收门店合集 - 讯息早知道

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号