[CF1477D] Nezzar and Hidden Permutations

news/2024/12/19 21:39:25/文章来源:https://www.cnblogs.com/Cyan0826/p/18617975

一开始看到这道题确实有种无从下手的感觉,具体说一说思考过程


  • 容易得出若 \(m = \frac{n(n-1)}{2}\),必定排列 \(p\)\(q\) 相等,思考若删掉一个限制之后会怎么样。

第一步是简单的,发现若删掉 \((l,r)\),那么只要 \(l\)\(r\) 中的元素是相邻的,那么 \(l\)\(r\) 的元素就可以交换了,也就自然而然在 \((l,r)\) 之间连了一条边。

  • 那再删一个限制呢?

如果互不影响,两两交换就可以了,但如果两个限制中的元素出现重复呢?手玩一下就会发现,若把这三个位置的元素表示成 \(y,y+1,y+2\),那可以构造出以下两个排列的元素(假定中间的元素是两个限制共用的元素):

\(p:(y+1,y,y+2)\)

\(q:(y,y+2,y+1)\)

所以我们得出:对于一个菊花图,必然存在一种方案使得两个排列相同位置的元素不相同,也就是说我们要将反图拆成多个点数 \(> 1\) 的菊花图。

  • 如何构造?

首先先把已经被限制死的点给删掉,剩下的图是不会出现单点的。

然后随便找一个生成树,我们手玩一下:

对于当前点 \(u\),设树中与它相连的点为 \(v\)

  1. \(v\) 作为菊花图的根的,直接连即可。
  2. \(v\) 所在的菊花图的大小 \(> 2\),把 \(v\) 让给 \(x\) 即可。
  3. \(v\) 所在的菊花图大小为 \(2\),把 \(x\) 加入不影响。

所以必然有解!然后就做完了。

点击查看代码
#include<bits/stdc++.h>
#define fir first
#define sec second
#define int long long
#define lowbit(x) x&(-x)
#define mkp(a,b) make_pair(a,b)
using namespace std;
typedef pair<int,int> pir;
inline int read(){int x=0,f=1; char c=getchar();while(!isdigit(c)){if(c=='-') f=-1; c=getchar();}while(isdigit(c)){x=x*10+(c^48); c=getchar();}return x*f;
}
const int inf=1e18,N=5e5+5;
int T;
int n,m;
int du[N];
int p[N],q[N];
vector<int> ed[N],re[N];
queue<int> qu;
set<int> s;
map<pir,int> mp;
inline void dfs(int x,int fa){for(auto it=s.begin();it!=s.end();it++){int v=*it;if(mp.find(mkp(x,v))==mp.end()){re[x].push_back(v);re[v].push_back(x);}}for(auto v:re[x]) if(v!=fa) s.erase(v);for(auto v:re[x]) if(v!=fa) dfs(v,x);
}
int vis[N],rt[N],siz[N],tot;
inline void dfs2(int x,int fa){if(!vis[x]){int fl=0;for(auto v:re[x]) fl|=(vis[v]==0);if(fl){vis[x]=++tot;rt[tot]=x;siz[tot]=1;for(auto v:re[x]) if(!vis[v]) vis[v]=tot,siz[tot]++;}else{for(auto v:re[x]){if(rt[vis[v]]==v){vis[x]=vis[v];siz[vis[v]]++;break;}if(siz[vis[v]]>2){siz[vis[v]]--;vis[x]=vis[v]=++tot;rt[tot]=x;siz[tot]=2;break;}rt[vis[v]]=v;vis[x]=vis[v];siz[vis[v]]++;break;}}}for(auto v:re[x]) if(v!=fa) dfs2(v,x);
}
inline void clear(){mp.clear();for(int i=1;i<=n;i++) ed[i].clear(),re[i].clear(),du[i]=0;s.clear();for(int i=1;i<=n;i++) vis[i]=siz[i]=rt[i]=p[i]=q[i]=0;tot=0;
}
inline void solve(){clear();n=read(),m=read();for(int i=1;i<=m;i++){int u=read(),v=read();ed[u].push_back(v);ed[v].push_back(u);mp[mkp(u,v)]=mp[mkp(v,u)]=1;du[u]++,du[v]++;}for(int i=1;i<=n;i++) s.insert(i);int cnt=0;for(int i=1;i<=n;i++) if(du[i]==n-1) qu.push(i),s.erase(i);while(!qu.empty()){int x=qu.front();qu.pop();p[x]=q[x]=++cnt;for(auto v:ed[x]){du[v]--;if((s.find(v)!=s.end())&&du[v]>=n-cnt-1){s.erase(v);qu.push(v);}}}for(int i=1;i<=n;i++) if(s.find(i)!=s.end()){s.erase(i);dfs(i,0);}for(int i=1;i<=n;i++) if(!vis[i]&&!p[i]) dfs2(i,0);for(int i=1;i<=tot;i++){int x=rt[i];p[x]=++cnt;for(auto v:re[x]){if(vis[v]!=i) continue;q[v]=cnt,p[v]=++cnt;}q[x]=cnt;}for(int i=1;i<=n;i++) cout<<p[i]<<' ';puts("");for(int i=1;i<=n;i++) cout<<q[i]<<' ';puts("");
}
signed main(){T=read();while(T--) solve();
}

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

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

相关文章

数量

技巧 比例型 出现一个比例,存在四种倍数关系倍数 你们有啥公因子,我也必须有尾数 出现乘法,分析个位,考虑尾数 。乘法中出现5和10尾数就确认了奇偶 与偶数相乘一定是偶数,与奇数相乘可能为偶数也可能为奇数拓展猜题 当 A = B*C ,求A ,考虑A的倍数 工程问题 利润问题 求最…

LVGL学习 - Visual Studio外部“.c.h”文件添加

LVGL项目工程添加“.c.h”文件后 “C1083”“LNK2019”报错的解决方法一、首先把文件添加至工程,现有项选择所需添加的“.c.h”文件但还是会有如下报错,解决方法在第2步。二、“.c”文件需要添加“extern "C"” 下图截至官方文档我试了只添加“extern "C"…

组合数学+ybt题解

加法原理 乘法原理 排列数 从 \(n\) 个数中任取 \(m\) 个元素的排列的方案数,表示为 \(A^m_n=\frac{n!}{(n-m)!}\) \(0!=1\) 全排列 \(A^n_n\) 组合数 从 \(n\) 个元素中取出 \(m\) 个元素的组合的个数,表示为 \(\dbinom{n}{m}= \frac{A^m_n}{m!}=\frac{n!}{m!(n-m)!}\) 如何…

苍穹外卖day02

JWT令牌、ThreadLocal、分页查询bug记录知识点记录新增员工新增员工需要填写创建人id和修改人id两个属性,这两个属性应该填本账户的id。 通过拦截器可以解析出JWT令牌中包含的登录员工id信息,但是该如何传递给Service的save方法? ThreadLocal并非一个Thread,而是Thread的局…

年底裁员开始了,大家做好准备吧!

各大互联网公司的接连裁员,政策限制的行业接连消失,让今年的求职雪上加霜,想躺平却没有资本,还有人说软件测试岗位饱和了,对此很多求职者深信不疑,因为投出去的简历回复的越来越少了。 另一面企业招人真的变得容易了吗?有企业HR吐槽,简历确实比以前多了好几倍,其实是变…

2024-2025-1 20241401 《计算机基础与程序设计》 第十三周学习总结

班级链接 2024计算机基础与程序设计作业要求 第十三周作业教材学习内容总结 《C语言程序设计》第12章结构体的定义和使用: 结构体类型的定义,以及结构体变量的创建和使用。结构体允许将不同数据类型的成员组合成一个整体,以便于管理和引用。 结构体变量的初始化: 结构体变量…

golang的互斥锁和读写锁

golang mutex(互斥锁) 1.锁最本质的作用 保证原子性 2.mutex 使用原则 适用于并发编程,尽量减少加锁区域的逻辑 3.mutex的局限性 仅限于单个进程内操作 sema(信号量,semaphore的简称)是一种用于并发控制的机制 资源计数:信号量维护一个资源计数。这个计数表示当前可用的资源数…

「测试人员」年终总结及来年规划

年底一般企业都会针对项目写总结,一般流程是组员呈交给组长,组长递交给测试经理,所以每个层级写各自的总结,会有不同的侧重点。 今天分别来聊聊测试工程师、测试组长以及测试经理年终总结的关注点在什么地方以及采用什么样的方法及策略使年终总结有实际意义且高大上。📝 …

【硬件测试】基于FPGA的2FSK调制解调系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR

1.算法仿真效果 本文是之前写的文章基于FPGA的2FSK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR_fpga 2fsk-CSDN博客的硬件测试版本。在系统在仿真版本基础上增加了ila在线数据采集模块,vio在线SNR设置模块,数据源模块。硬件ila测试结果如下:(…

征程 6 云端 Ota 升级方案设计与实现

01 引言 在开发、调测过程中,经常通过 Ota 技术升级应用软件、底软。目前,项目上已将 Matrix6 的 Demo 部署在实车上,每次软件、底软需要版本更替或版本升级时,都需要研发测试同学上到车上使用工控机进行手动升级。 这流程存在耗费人力多,花费时间长,流程易出错的问题,并…

vxe-table 树表格新增数据,插入指定节点位置操作

vxe-table 新增数据,插入指定节点位置操作 官网:https://vxetable.cn npm install vxe-pc-ui@4.3.37 vxe-table@4.9.31// ... import VxeUI from vxe-pc-ui import vxe-pc-ui/lib/style.css import VxeUITable from vxe-table import vxe-table/lib/style.css // ...createAp…