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

完整教程:SCP2025T2:P14254 分割(divide) 题解

完整教程:SCP2025T2:P14254 分割(divide) 题解

P14254 分割(divide)

题面上的 1 ≤ p i < i 1 \leq p_i < i1pi<i是不是有问题啊,应该是1 ≤ p i ≤ i 1 \leq p_i \le i1pii吧,定义为:第i ii个正整数表示结点( i + 1 ) (i+1)(i+1)的父结点的编号p i p_ipi

思路

首先我们记以i ii为根的子树中深度最深的点的深度为m i m_{i}mi,则 S i = [ d i , m i ] S_{i}=[d_{i},m_{i}]Si=[di,mi]。可以发现,如果d b 1 < d b i ( 1 < i ≤ n ) d_{b_1}< d_{b_i}(1<i\le n)db1<dbi(1<in),那么 d b 1 ∉ S j d_{b_1}\notin S_{j}db1/Sj,求交集后一定不会满足条件二。故d b 1 = d b 2 = ⋯ = d b k d_{b_1}=d_{b_2}=\dots=d_{b_k}db1=db2==dbk

我们把深度相同的点放进桶里,针对同一深度的点,从小到大枚举m i m_{i}mi 的值。设 c n t cntcnt 为相等的 m i m_{i}mi 的个数,p pp 为比 m i m_{i}mi小的值的的个数,s ss 为比 m i m_{i}mi大的值的个数。显然,比m i m_{i}mi小的值必然不可能成为被挖去的子树,如果挖去,那么交集后一定不会满足条件二。我们首先钦定一个m i m_{i}mib 1 b_1b1,那么就是在剩下s + c n t − 1 s+cnt-1s+cnt1个子树中选择k − p − 1 k-p-1kp1个挖去,剩下的保留。有问题吗?当然有,倘若所有相等的m i m_{i}mi都没有被挖去,且至少有一个比m i m_{i}mi大的没有被挖去,那么交集就不满足条件二了,减去这种情况即可。

代码

时间复杂度 O ( n log ⁡ M ) O(n\log_{}{M} )O(nlogM),其中 M = 998244353 M=998244353M=998244353,不过允许优化求逆元的复杂度可以得到O ( n log ⁡ n ) O(n\log_{}{n} )O(nlogn),懒得改了。

#include<bits/stdc++.h>using namespace std;const int N=1e6+5,mod=998244353;int n,k,dep[N],m[N],jie[N],ni[N];vector<int> a[N],t[N];void dfs(int x){m[x]=dep[x];for(int i=0;i<a[x].size();i++){dep[a[x][i]]=dep[x]+1;dfs(a[x][i]);m[x]=max(m[x],m[a[x][i]]);}t[dep[x]].push_back(m[x]);}int ksm(int x,int y){if(y==1) return x;long long mid=ksm(x,y>>1);if(y&1) return mid*mid%mod*x%mod;else return mid*mid%mod;}int C(int n,int m){if(m==0) return 1;if(n<m||n<0||m<0) return 0;return 1ll*jie[n]*ni[n-m]%mod*ni[m]%mod;}int main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>n>>k;for(int i=2;i<=n;i++){int p;cin>>p;a[p].push_back(i);}jie[0]=1;for(int i=1;i<=n;i++)jie[i]=1ll*jie[i-1]*i%mod,ni[i]=ksm(jie[i],mod-2);//直接用的快速幂求逆元,时间稍微多些dep[1]=1;dfs(1);long long ans=0;for(int i=2;i<=n;i++){sort(t[i].begin(),t[i].end());for(int j=0;j<t[i].size();){int cnt=0,p=j;for(int d=j;d<t[i].size();d++)if(t[i][d]==t[i][j]) cnt++;else break;int s=t[i].size()-j-cnt;long long sum=C(s+cnt-1,k-1);if(s>k-1)sum=(sum-C(s,k-1))%mod;//在s中取k-1个挖去,剩下的给根节点,保证至少给根节点一个ans=(ans+sum*cnt%mod)%mod;//任意一个都可以当b1j+=cnt;}}ans=ans*jie[k-1]%mod;//序列b有序,要乘上排列数ans=(ans+mod)%mod;//涉及减法,可能出现负数cout<<ans;return 0;}
http://www.jsqmd.com/news/318972/

相关文章:

  • Java毕设项目:基于springboot的办公用品管理系统小程序的设计与实现(源码+文档,讲解、调试运行,定制等)
  • 2026广东最新劳动纠纷机构top5推荐!深圳等地公司深度解析,高效维权保障劳资权益
  • Java的类
  • 效率工具PcDrawer(归类整理快速打开)一款高效的归类整理和快速打开工具
  • 从零开始:贯通硬件与UI的高效LCD开发全攻略
  • 实测有效的降ai率工具深度横评:手把手教你降低ai率,3分钟完成免费降aigc
  • 数字人SadTalker一张照片根据音频驱动说话数字人软件及安装教程整合版
  • 基于Air780EHV核心板的OTP核心库API使用详解!
  • 【计算机毕业设计案例】基于springboot的剧本杀游玩一体化平台小程序的设计与实现(程序+文档+讲解+定制)
  • 2026年最新的免费降ai率神器汇总:告别付费陷阱,降ai效果哪款好?【附降ai率方法】
  • 基于微信小程序的闲置物品交易平台的设计与实现
  • AI编程案例:基于 Vue3 + Leaflet 开发的中国省市两级地理数据可视化系统
  • 企业领域 - 跨部门轮岗
  • 【AIGC】Seedream 、FLUX 、qwen 及LORA
  • 科技守护温情,智慧康养让陪伴跨越距离
  • 最新“学生必考”AI证书,真的在慢慢贬值吗?
  • 2026年论文降ai最全避坑指南:3招论文降aigc奇招+5款最稳的降ai率工具深度评测
  • OxCal在线工具进行C14BP到 BCE的矫正
  • @private 、@protected 和 @readonly 的区别是什么?
  • 23. 抗锯齿
  • 理解Spark RDD
  • Java毕设项目推荐-基于微信小程序的狼人杀桌游预约拼团小程序设计与实现基于springboot的剧本杀游玩一体化平台小程序的设计与实现【附源码+文档,调试定制服务】
  • Flutter for OpenHarmony 视力保护提醒App实战 - 错误处理与异常管理
  • samlib.dll文件丢失找不到问题 免费下载方法分享
  • 2026 年后端开发者路线图
  • sudo命令和su 的区别
  • 高并发服务器组件单元测试集成测试架构测试
  • 计算机Java毕设实战-基于springboot的剧本杀游玩一体化平台小程序的设计与实现剧本杀狼人杀桌游预约小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 从迎宾展示到数据闭环:校园智能接待机器人的技术演进与应用现状
  • 22. 纹理采样