[AGC59C] Guessing Permutation for as Long as Possible
Problem Statement
A teacher has a hidden permutation $P=(P_1,P_2,\ldots,P_N)$ of $(1,2,\cdots,N)$.
You are going to determine it.
To do this, you prepared a sequence of pairs of integers $(A_1,B_1),(A_2,B_2),\ldots,(A_{N(N-1)/2},B_{N(N-1)/2})$; this is a permutation of all pairs of the form $(a,b)$ ($1 \le a < b \le N$).
Now, you will go over the pairs from the beginning. For a pair $(A_i, B_i)$, you will ask if $P_{A_i}<P_{B_i}$, and the teacher will tell you the answer.
However, you will skip this question if you can already determine the answer to it from previous answers.
Find the number of permutations $P$, for which with your algorithm you will have to ask all $\frac{N(N-1)}{2}$ questions, modulo $10^9+7$.
Constraints
- $2 \le N \leq 400$
- $1 \le A_i < B_i \le N$
- $(A_i,B_i) \neq (A_j,B_j)$ ($i \neq j$)
- All values in the input are integers.
Input
Input is given from Standard Input in the following format:
$N$
$A_1$ $B_1$
$A_2$ $B_2$
$\vdots$
$A_{N(N-1)/2}$ $B_{N(N-1)/2}$
Output
Print the answer.
Sample Input 1
2
1 2
Sample Output 1
2
Clearly, for any permutation $P$, you need to ask $1$ question.
Sample Input 2
4
1 2
1 3
2 3
2 4
3 4
1 4
Sample Output 2
4
Consider $P=(2,3,1,4)$ as an example.
In this case, you will skip the third question since you know $P_1 < P_2$ and $P_1 > P_3$ from previous questions and you can determine $P_2 > P_3$.
Therefore, $P=(2,3,1,4)$ should not be counted.
Sample Input 3
5
1 2
2 3
3 4
4 5
1 5
1 3
2 4
3 5
1 4
2 5
会发现如果我们给每一个询问钦定了答案,那么最后的序列可以由我们钦定的答案推出。仔细想想,一个答案序列只对应一个排列,一个排列也只对应一个答案序列。所以我们去考虑有多少种钦定答案的方式。
这还不简单,\(2^{n*(n-1)/2}\) 种吗。肯定不对,不对就在于会出现冲突。而且按照题目的要求,我们不能由某两个询问去推出后面的询问的答案。
如果现在有两个询问 \((a,b)\) 和 \((b,c)\),他们的回答都为真的话,我们可以推断出 \(p_a<p_c\),而如果询问 \((a,c)\) 还没被问到,那就不好了。所以出现这种情况时,如果 \((a,b)\) 为真,\((b,c)\) 必定为假,如果 \((a,b)\) 为假, \(b,c\) 必定为真。
那么考虑使用并查集维护。之所以不用 2-sat 是因为这里的边是双向的。知道了 \((a,b)\) 为假时 \((b,c)\) 必定为真,而 \((b,c)\) 为真时 \((a,b)\) 必然为假。可以参考上面的例子得知。并查集中一个记录为真的域,一个记录为假的域。然后把互相之间可以推出的一些关系合并。
具体而言,枚举到一个询问,枚举之前的询问,判断四个数中是否有两个相等,如果有,那就按照上面的方式连边就好了。有时候是真真连假假连,有时候是真假互相连。但这样复杂度 \(O(n^4)\)
考虑优化,发现我们要四个数中有两个相等。可以用vector记录下那些询问 \(a_i=x\),哪些询问满足 \(b_i=y\)。然后每次只用遍历vector中的数,分成四种情况。这样复杂度就是 \(O(n^3)\).
如果最终某一个询问为真可以推出这个询问为假,无解。这个图极具对称性,如果 \(a_1(True),a_2(False),a_3(True)\) 在一个连通块,那么 \(a_1(False),a_2(True),a_3(False)\) 也在一个连通块。而这两种答案序列分配方式任选一个都是可以的。所以如果最后总共有 \(c\) 个连通块,答案为 \(2^{\frac c2}\)
#include<bits/stdc++.h>
using namespace std;
const int N=805,P=1e9+7;
int fa[N*N],n,v[N][N],m,a[N*N],b[N*N],cnt,pw=1;
vector<int>ga[N],gb[N];
int find(int x)
{
if(fa[x]==x)
return x;
return fa[x]=find(fa[x]);
}
int main()
{
scanf("%d",&n),m=n*(n-1)/2;
for(int i=1;i<=m;i++)
{
// printf("%d\n",i);
fa[i]=i,fa[i+m]=i+m;
scanf("%d%d",&a[i],&b[i]);
v[a[i]][b[i]]=v[b[i]][a[i]]=1;
for(int j=0;j<ga[a[i]].size();j++)
{
if(!v[b[i]][b[ga[a[i]][j]]])
{
fa[find(ga[a[i]][j]+m)]=find(i+m);
fa[find(ga[a[i]][j])]=find(i);
}
}
// puts("hjhyyds");
for(int j=0;j<gb[b[i]].size();j++)
{
if(!v[a[i]][a[gb[b[i]][j]]])
{
fa[find(gb[b[i]][j]+m)]=find(i+m);
fa[find(gb[b[i]][j])]=find(i);
}
}
// puts("hjhakioi");
for(int j=0;j<ga[b[i]].size();j++)
{
if(!v[a[i]][b[ga[b[i]][j]]])
{
fa[find(ga[b[i]][j]+m)]=find(i);
fa[find(ga[b[i]][j])]=find(i+m);
}
}
// puts("qzmyyds");
for(int j=0;j<gb[a[i]].size();j++)
{
if(!v[b[i]][a[gb[a[i]][j]]])
{
fa[find(gb[a[i]][j]+m)]=find(i);
fa[find(gb[a[i]][j])]=find(i+m);
}
}
// puts("qzmakioi");
ga[a[i]].push_back(i);
gb[b[i]].push_back(i);
// for(int j=1;j<i;j++)
// {
// if(a[i]==b[j]&&!v[a[j]][b[i]]||a[j]==b[i]&&!v[a[i]][b[j]])
// {
// fa[find(i+m)]=find(j);
// fa[find(i)]=find(j+m);
// }
// }
}
for(int i=1;i<=2*m;i++)
{
if(find(i)==find(i+m))
{
puts("0");
return 0;
}
if(fa[i]==i)
++cnt;
}
for(int i=1;i<=cnt/2;i++)
(pw<<=1)%=P;
printf("%d",pw);
}
[AGC59C] Guessing Permutation for as Long as Possible的更多相关文章
- Permutation Sequence
The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- [LeetCode] Palindrome Permutation II 回文全排列之二
Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...
- [LeetCode] Palindrome Permutation 回文全排列
Given a string, determine if a permutation of the string could form a palindrome. For example," ...
- [LeetCode] Permutation Sequence 序列排序
The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- [LeetCode] Next Permutation 下一个排列
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
- Leetcode 60. Permutation Sequence
The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- 2632: [neerc2011]Gcd guessing game
2632: [neerc2011]Gcd guessing game Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 144 Solved: 84[S ...
- UVA11525 Permutation[康托展开 树状数组求第k小值]
UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...
- Permutation test: p, CI, CI of P 置换检验相关统计量的计算
For research purpose, I've read a lot materials on permutation test issue. Here is a summary. Should ...
- Permutation
(M) Permutations (M) Permutations II (M) Permutation Sequence (M) Palindrome Permutation II
随机推荐
- docker 搭建php环境(踩坑经验!!)
本次安装的推荐配置: nginx 1.24.0 mysql 5.7.43 php 7.4.3-fpm redis 7.2.0 一.安装虚拟机 vm虚拟机需要4g内存,网络使用nat模式设置静态ip ...
- 【pandas小技巧】--花哨的DataFrame
最近github上发现了一个库(plottable),可以用简单的方式就设置出花哨的 DataFrame 样式. github上的地址:https://github.com/znstrider/plo ...
- Java 设计模式实战系列—单例模式
本文首发公众号:小码A梦 单例模式是设计模式中最简单一个设计模式,该模式属于创建型模式,它提供了一种创建实例的最佳方式. 单例模式的定义也比较简单:一个类只能允许创建一个对象或者实例,那么这个类就是单 ...
- PDF 补丁丁 1.0 正式版
经过了一年多的测试和完善,PDF 补丁丁发布第一个开放源代码的正式版本了. PDF 补丁丁也是国内首先开放源代码.带有修改和阅读PDF的功能的 PDF 处理程序之一. 源代码网址:https://gi ...
- iOS日志获取
IOS日志获取 崩溃日志存放目录: /var/mobile/Library/Logs/CrashReporter
- MySQL面试题——隔离级别相关面试题
隔离级别相关面试题 MySQL事务隔离级别 未提交读--可以读到其他事务未提交的数据(最新的版本) 错误现象:脏读.不可重复读.幻读的现象 提交读(RC)--可以读到其他事务已提交的数据(最新已提交的 ...
- Solution -「THUPC 2021」区间矩阵乘法
Description Link. 给定长度为 \(n\) 的序列 \(a_1, a_2, \dots, a_n\):共 \(m\) 组询问,每次询问给出 \(d,p_1,p_2\),求 \[\sum ...
- RK3568开发笔记(十一):开发版buildroot固件移植一个ffmpeg播放rtsp的播放器Demo
前言 目标开发任务还有个功能,就是播放rtsp摄像头,当然为了更好的坐这个个,我们必须支持rtsp播放失败之后重新尝试,比如5s重新尝试打开一次,从而保障联网后重新打开,然后达成这个功能. D ...
- containerd镜像拉取配置
背景: 公司要求部署最一套新版的k8s系统来部署生产应用,说实话很头疼.因为k8s自1.23版本之后就用不docker作为容器的默认运行时了,而是采用的containerd,这就带来了一系列的问题.没 ...
- EarthChat SignalR原理讲解
SignalR原理讲解 SignalR是什么? SignalR 是 Microsoft 开发的一个库,用于 ASP.NET 开发人员实现实时 web 功能.这意味着服务端代码可以实时地推送内容到连接的 ...