当前位置: 首页 > news >正文

Codeforces Round 1095 (Div. 2) F. Inversion Invasion

总体而言,本题需要用到的技巧有:排列组合数、gcd分桶排列的平均逆序对数。是有点思维量的题目,需要不少技巧。

1.排列的平均逆序对数

想要写出这题,应该比较清楚地理解排列的平均逆序对数这一概念。对于一个普通的 n! 排列,它的每一组排列的平均逆序对数是,意思是以的概率选中一组逆序对,这样的逆序对一共有"组合数里的n个里面选2个"种。

对于无附加条件的长度为n的普通排列,它的平均逆序对个数

2.gcd分桶在本题的用处

gcd 分桶带来的对称性,和排列的平均逆序对数高度相关。

gcd 分桶的对称性:对于,有

也是因为这个对称性,所以这也相当于,这个和普通随机排列的情况是一致的。所以对于本题的数字 1 至 n-1 都是上面的公式,只身下一种特殊情况,也就是数字 n 的情况。

gcd 分桶可以快速求出的时候,有多少个满足条件。这是本题求出合法排列数的方法。

3.特殊情况x==n

kk=,意思是普通 1 至 n-1 的情况,以及减去 x==n 的情况的贡献。

情况一:x=n 出现过

此时 n 被固定在位置:pos

因为 n 是最大值,它只会和后面的数形成逆序对。产生贡献为n - pos

对应代码:

if(pos) ans*=(kk+(n-pos)+P)%P;

情况二:x=n还没出现

此时 n 可以在任意自由位置。

设自由位置数量:F

自由位置下标和:S

所以 n 的平均位置可以表示为,产生贡献为n -

对应代码:

else ans*=(kk+(n-S%P*inv(F)%P))%P;

所以最终答案就是 ans = 合法排列数量 × 每组排列的平均期望逆序对数

ans =* gcd分桶的排列选取情况 *(),n 未固定时 pos 为;已固定时为固定值 pos (保存在这个变量里面)。

C++代码如下:

#include<bits/stdc++.h> #define int long long using namespace std; const int P=998244353LL; int T,n,q,i,x,S,F,inv2,inv4; int f[2000009],g[2000009],h[2000009]; int fac[2000009],nifac[2000009],ans,anss,kk,pos; int ksm(int a,int p){ if(p==0)return 1; int kk=1;a%=P;p%=P; while(p>1){ if(p%2==0){ p/=2; a*=a; a%=P; } else{ p--; kk*=a; kk%=P; } } kk*=a;kk%=P; return kk; } void Pre(){ for(int i=1;i<=n;i++)f[i]=g[i]=h[i]=0; for(int gcd=n;gcd>=1;gcd--){ for(int i=1;i*gcd<=n;i++){ int j=i*gcd; if(f[j]==0&&n%gcd==0){ f[j]=gcd; g[gcd]++;h[gcd]++; } } } } int inv(int x){ return ksm(x,P-2); } int A(int x,int y){ if(x<y||x<0||y<0)return 0; int ans=fac[x]; ans*=nifac[y];ans%=P; return ans; } signed main(){ ios::sync_with_stdio(false);cin.tie(0); fac[0]=nifac[0]=1;inv2=inv(2);inv4=inv(4); for(i=1;i<=2000000;i++){ fac[i]=fac[i-1]*i;fac[i]%=P; nifac[i]=inv(fac[i]); } cin>>T; while(T--){ cin>>n>>q;pos=0; kk=(n*(n-1)%P*inv4%P-(n-1)*inv2%P+P)%P; S=0;F=n;Pre();anss=1; for(i=1;i<=n;i++)S+=i; while(q--){ cin>>i>>x; F--;S-=i;if(x==n)pos=i; ans=fac[F]; anss*=inv(A(g[x],h[x]));anss%=P; h[x]--; anss*=A(g[x],h[x]);anss%=P; ans*=anss;ans%=P; if(pos)ans*=(kk+(n-pos)+P)%P; else ans*=(kk+(n-S%P*inv(F)%P))%P; ans=(ans%P+P)%P; cout<<ans<<'\n'; } } return 0; }
http://www.gsyq.cn/news/1461139.html

相关文章:

  • Python异步架构深度解析:构建高性能B站数据采集系统实战指南
  • 3步掌握专业缠论分析:ChanlunX通达信插件完全指南
  • 影刀RPA实战:用Python从零打造TikTok店群全自动运营系统,一人轻松扛起200店
  • 解读 `signal(SIGPIPE, SIG_IGN);`
  • po审批问题
  • 2026 上海零基础电工培训怎么选?从资质维度拆解择校避雷方法 - 新闻观察者
  • 奇迹 MU 荣耀出征手游官网下载:荣耀出征最新官方下载渠道
  • 新手福音:在快马平台借助Codex重连机制,无忧开启你的第一行代码
  • WindowResizer:如何突破Windows窗口限制,打造个性化桌面布局?
  • 2026惠州黄金回收避坑指南!拆解五大套路,认准中检认证的惠奢汇(惠城旗舰店) - 生活测评小能手
  • 2026 沈阳名包回收 TOP5 实测盘点|闲置奢品变现指南 - 奢侈品回收评测
  • 盘锦市2026年黄金回收白银回收铂金回收权威门店 TOP5+正规可靠机构电话与地址汇总 - 中安检金银铂钻回收
  • 告别臃肿:5分钟上手G-Helper,让你的华硕笔记本重获新生
  • Java 资深工程师面试全维度解码
  • 终极指南:如何用开源工具轻松解密RPG Maker MV/MZ加密资源
  • OpenCV入门实战:人脸检测、背景移除、边缘检测与图像模糊
  • AHP层次分析法在水利中的实践技术应用
  • 2026年宁波市口碑首选!黄金回收铂金回收白银回收权威门店 TOP5 附咨询电话 - 信誉隆金银铂奢回收
  • 效率飞跃:借助快马AI用点运算符优化你的对象访问代码
  • Axure中文界面改造指南:5分钟让英文设计工具说中文
  • 别再为LabVIEW机器视觉安装发愁了!手把手教你搞定VDM和VAS(附离线安装包获取)
  • 2026年衡阳市黄金回收白银回收铂金回收门店 TOP5榜单无套路:实体店铺地址电话一览 - 诚金汇钻回收公司
  • Java动态代理详解:小白也能彻底搞懂动态代理!
  • Typora格式规范检测终极指南:让Markdown写作更专业更高效
  • Arduino音乐播放器实战:从PWM原理到嵌入式系统设计
  • 2026年新疆高新技术企业申报时间流程及南北疆差异化补贴细则
  • 漯河市2026年黄金回收白银回收铂金回收放心选真心推荐 靠谱门店排行 + 联系电话整理 - 中业金奢再生回收中心
  • 如何用OpenMir2快速搭建热血传奇游戏服务器:C完整实战指南
  • VR-Reversal:免费解锁VR视频的终极观看指南,让3D内容在普通设备自由播放!
  • Grok4 API低成本接入实战:绕过付费墙的合规工程路径