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的更多相关文章

  1. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  2. [LeetCode] Palindrome Permutation II 回文全排列之二

    Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...

  3. [LeetCode] Palindrome Permutation 回文全排列

    Given a string, determine if a permutation of the string could form a palindrome. For example," ...

  4. [LeetCode] Permutation Sequence 序列排序

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  5. [LeetCode] Next Permutation 下一个排列

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  6. 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 ...

  7. 2632: [neerc2011]Gcd guessing game

    2632: [neerc2011]Gcd guessing game Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 144  Solved: 84[S ...

  8. UVA11525 Permutation[康托展开 树状数组求第k小值]

    UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...

  9. 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 ...

  10. Permutation

    (M) Permutations (M) Permutations II (M) Permutation Sequence (M) Palindrome Permutation II

随机推荐

  1. Go学习笔记1

    学习路线 2023-Go全链路工程师课纲 https://www.processon.com/view/link/63594cd97d9c0854f9ac855e 一.搭建环境 https://stu ...

  2. 面试题:Mybatis中的#{}和${}有什么区别?这是我见过最好的回答

    面试题:Mybatis中的#{}和${}有什么区别? 前言 今天来分享一道比较好的面试题,"Mybatis中的#{}和${}有什么区别?". 对于这个问题,我们一起看看考察点和比较 ...

  3. P251——用RadialGradientBrush填充椭圆,并进行RotateTransform变换

    一.认识RadialGradientBrush(径向渐变) 1.坐标 RadialGradientBrush可以用来填充矩形(正方形)和椭圆(正圆), 填充区域使用比例坐标, 椭圆的坐标(0,0)和( ...

  4. Solution -「HDU 3507」Print Article

    Description Link. 给出 \(N\) 个单词,每个单词有个非负权值 \(C_{i}\),现要将它们分成连续的若干段,每段的代价为此段单词的权值和,还要加一个常数 \(M\),即 \(( ...

  5. Teamcenter RAC开发 GoToHelper

    RAC开发,有时候会用到发送到我的Teamcenter 可以参考 com.teamcenter.rac.tcapps 包下 package com.teamcenter.rac.tracelinks; ...

  6. No module named virtualenvwrapper 虚拟环境报错

    No module named virtualenvwrapper 虚拟环境报错 安装虚拟环境命令 sudo pip install virtualenv sudo pip install virtu ...

  7. MySQL事务死锁问题排查

    一.背景 在预发环境中,由消息驱动最终触发执行事务来写库存,但是导致MySQL发生死锁,写库存失败. com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionR ...

  8. fmpeg 多张图片转视频,视频转gif,截取视频,截取视频里的帧

    ffmpeg 多张图片转视频,视频转gif,截取视频,截取视频里的帧 月色下的独轮车 于 2017-06-20 17:32:01 发布 6250 收藏 3文章标签: ffmpeg版权 android学 ...

  9. Python如何在日志中隐藏明文密码

    Python如何在日志中隐藏明文密码 前言 在项目开发中,有的时候会遇到一些安全需求,用以提升程序整体的安全性,提高外来非法攻击的门槛,而在日志中隐藏明文密码打印便是最典型的安全需求之一. 在Pyth ...

  10. Go 函数多返回值错误处理与error 类型介绍

    Go 函数多返回值错误处理与error 类型介绍 目录 Go 函数多返回值错误处理与error 类型介绍 一.error 类型与错误值构造 1.1 Error 接口介绍 1.2 构造错误值的方法 1. ...