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

F1005D. 「阶段测试5」合影

题意:

\(n\) 个人排成一排,每个点 \(i\) 最多会给出一条限制,形如 \((i,j)\) 表示点 \(i\) 必须站在 \(j\) 的左侧。问有多少种成立的方案数,答案对输入的模数 \(p\) 取模。

对于\(100\%\) 的数:\(n≤2\times 10^5,m≤2\times 10^5,m≤n,n+10≤p≤10^9+7,T≤10\).

题解:

给个不一样的做法,应该好写一点。

我们考虑限制构成什么,先用限制构造边 \(i\to j\),发现如果所有 \(i\) 都有出边那么这玩意会构成外向基环树森林,但是我们会发现如果有环,那一定无解,所以在有解的情况下会构成一棵树。

现在再思考限制的本质,对于 \(i\to j\), 这是一个经典的问题,等价于满足构成的树上 \(i\) 的拓扑序小于 \(j\)

对于这个经典的有根树版本问题我们有一个经典的结论:

\[ans=\frac{n!}{\prod^{n}_{i=1}siz_i} \]

其中 \(siz_i\)\(i\) 的子树大小。考虑怎么把我们的限制构造成有根树,发现我们把 \(i\to j\) 都换成 \(j\to i\) 答案肯定是不变的,把题意理解成 \(i\)\(j\) 的右侧即可。这样一定是有根树。

证明:

考虑一般情况,若发现如果所有 \(i\) 都有出边那么这玩意会构成内向基环树森林。考虑删掉环的一些部分使得有答案,那么你一定可以找到一个根在环上一点。

那么直接做就可以了。时间复杂度 \(O(Tn)\).

细节:预处理逆元可以做到线性,这里还有一个性质值得注意,数据范围里写了 \(n+10\le p\),这使得我们可以直接处理逆元,因为如果 \(n\ge p\) 的话我们就要用 \(lucas\) 定理了。

code:

#include<bits/stdc++.h>
#define pb push_back
#define int long long
#define m(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=2e5+10;
int n,m,k,T,siz[N],vis[N],cnt,tg,mod,ni[N],ans;
vector<int> g[N];
int ksm(int x,int k){int ans=1;while(k){if(k&1) ans=ans*x%mod;x=x*x%mod;k>>=1;}return ans;
}
void dfs(int u){vis[u]=cnt;siz[u]=1;for(int v:g[u]){if(vis[v]==cnt){tg=1;break;	}else if(!vis[v]) dfs(v);siz[u]+=siz[v];}
}
void init(){rep(i,1,n) g[i].clear();tg=0;cnt=0;m(siz);m(vis);ni[1]=1;ans=1;rep(i,2,n) ni[i]=(-mod/i*ni[mod%i]%mod+mod)%mod;
}
signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);cin>>T;while(T--){cin>>n>>m>>mod;init();rep(i,1,m){int x,y;cin>>x>>y;g[y].pb(x);}rep(i,1,n){if(!vis[i]) cnt++,dfs(i);}if(tg==1){cout<<0<<'\n';continue;}rep(i,1,n){ans=ans*i%mod;ans=ans*ni[siz[i]]%mod;}cout<<ans<<'\n';}return 0;
}

官方解法:

算法1

对于 15%的数据 我们可以直接枚举所有置换,再进行判断即可,时间复杂度$ O(T*n!)$

算法2

对于 50%的数据 定义$ f[S]$表示已经选了元素集合为 \(S\) 的合法方案数是多少, 转移方程为 \(f[S]=∑ 𝑓[𝑆 − 2^x ]\),满足 x 是 S 中的元素且所有限制 均不矛盾,可以先预处理每个位置不合法状态的集合,这样 时间复杂度 \(O(n T *2^n)\),如果你写成 \(O(n*n*T*2^n)\),那么 恭喜你,你只有 30(常数小的除外)分了。

算法3

对于余下所有数据, 我们需要观察出一些性质。
如果我们对于一条限制 \((x, y)\), 建一条 \(x->y\) 的边, 就会发 现在这张图中每个点的出边最多只有一条。

如果在这张图中有环, 则答案一定为 0 。
如果这张图无环, 则这些边一定构成一个森林。
所以我们可以跑树形 dp。

定义 \(f[i]\) 表示第 \(i\) 棵子树的方案数是多少。
转移时, 相当于有很多的儿子 \(s_{1}, s_{2} \ldots s_{n}\) (设每个儿子的子树 大小为 size), 相当于对于一个序列中, 先选 1 个位置给 \(s_{1}\),
再在余下的位置中, 选 2 个位置给 \(s_{2} \ldots\), 相当于一些组合数的 乘积再乘以每个儿子内部的方案数。

算法4

对于 \(70 \%\) 的数据

我们可以利用组合恒等式 \(c_{x}^{y}=c_{x-1}^{y}+C_{x-1}^{y-1}\) 预处理组合数, 或是预 处理逆元暴力求组合数, 复杂度均为 \(O\left(T^{*} n * n\right)[m\) 一定小 于等于 \(n\), 所以 \(m\) 近似为 \(n\) ]

算法5

对于 \(100 \%\) 的数据

我们可以先预处理阶乘, 阶乘的逆元, 然后组合数就可以 \(\mathrm{O}(1)\) 了, 总复杂度为 \(O\left(T^{*}(n+m)\right)\)

http://www.gsyq.cn/news/21382.html

相关文章:

  • 原创2020年纽约市交通事故数据集深度解析:基于74,881条记录的智能交通管理与自动驾驶算法训练实战指南,覆盖超速、分心驾驶、天气因素等多维度事故原因分析,助力城市安全治理从被动应对转向主动预防
  • 原创1747张YOLO标注奶牛水牛识别数据集:精准标注跨场景动物检测模型训练专用计算机视觉数据集,助力智慧农业与畜牧业AI算法研发
  • 原创1
  • 2025 最新开锁公司口碑排行榜权威甄选:智能锁 / 汽车锁 / 保险柜开锁服务最新推荐,安全高效品牌指南
  • 2025 年摇臂钻床厂商最新推荐排行榜:含 3050/3080/3040/3063/50 型号厂家产能与供应优势详解
  • 20232402 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 2025 年最新推荐排水沟厂家排行榜:聚焦树脂 / 线性 / 树脂混凝土 / 成品 /u 型排水沟优质厂家推荐
  • AC6966B SD配置F组可以吗?ok
  • 内网穿透的原理和安装
  • Morlet小波分析详解
  • Gitee vs. GitHub 2025:中国开发者为何更青睐本土代码托管平台?
  • 主线程阻塞型帧堆积(Frame Backlog)
  • ROS 传感器模块的通用架构设计与跨中间件扩展实践
  • 替代传统FTP的系统:企业数字化转型新选择
  • 需求分析论
  • 别再空谈数据价值!制造业如何用主数据管理 “抠” 出千万级成本?
  • 2025年注塑加工行业优质企业最新推荐排行榜:助力需求企业精准筛选可靠合作伙伴
  • 被 Excel 格式折腾的那些瞬间---excl格式转换
  • 内外网传文件有哪些痛点?一文读懂高效传输方案是什么样的
  • 内存的堆、内存的栈有什么区别
  • 用 AI 批量优化思源笔记排版
  • 2025 年连接线线束厂家最新推荐榜:新能源电子 / 机器人电子等多领域优质企业品控、定制能力及合作案例全面盘点
  • 2025 年试验机最新推荐榜单:电子万能材料 / 橡胶拉力 / 塑料拉力 / 环刚度 / 冲击试验机优质厂家精选及科研工业合作参考
  • 2025 年国内卷帘门源头厂家最新推荐排行榜:电动 /pvc/ 钢质 / 自动 / 防火卷帘门优质厂家精选
  • 如何让AI实现自动化 —— PlayWright MCP 实测 - 教程
  • 2025 年济南画室最新推荐榜单:聚焦小班教学与全封闭管理,权威解析优质画室品牌榜山东画室推荐
  • 2025年无锡黄金回收商家电话最新权威推荐榜:专业鉴定与高价回收口碑之选,黄金回收公司推荐
  • 使用git-filter-repo 清除大文件
  • C# 23种设计模式详解与示例 - 详解
  • 2025年最新销售管理系统使用指南:顶级销售是如何使用CRM系统? - SaaS软件