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. 这才叫 API 接口设计!

    API 接口设计 Token 设计 Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上 ...

  2. 如何利用电商API接口来获取商品数据

    要利用电商API接口来获取商品数据,我们可以按照以下步骤实现: 确定电商平台和API接口 不同的电商平台提供不同的API接口,因此我们需要确定我们要获取商品数据的电商平台,并选择相应的API接口进行调 ...

  3. 本地项目上传到Git仓库

    1. 进入项目主目录,打开Git Bash,执行以下命令,将项目变为一个git管理的项目: $ git init 执行成功后,会在项目根目录生成一个.git的文件夹. 可以执行以下命令查看项目状态: ...

  4. Go代码包与引入:如何有效组织您的项目

    本文深入探讨了Go语言中的代码包和包引入机制,从基础概念到高级应用一一剖析.文章详细讲解了如何创建.组织和管理代码包,以及包引入的多种使用场景和最佳实践.通过阅读本文,开发者将获得全面而深入的理解,进 ...

  5. EXE一机一码打包加密大师1.4.0更新-支持导出注册机

    EXE一机一码打包加密大师可以对EXE文件进行加密处理,可以让EXE支持一机一码功能,也可以支持静态打开密码功能, 方便开发人员想用户收费. 详细软件使用说明可以查看下面的说明文档: EXE一机一码打 ...

  6. Oracle主键自增列

    SQL Server创建主键自增列我们可以使用"ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY"一步到位创建,而Oracle创建主键自增列和SQ ...

  7. redisson分布式锁的应用——秒杀、超卖 简单例子(分布式锁相关)

    1.常见的分布式事务锁 1.数据库级别的锁 乐观锁,给予加入版本号实现 悲观锁,基于数据库的for update实现 2.Redis,基于SETNX.EXPIRE实现 3.Zookeeper,基于In ...

  8. 织梦DEDEBIZ调用全站文章数量

    织梦DEDEBIZ如何调用全站文章数量{dede:sql sql="select count(*) as c from biz_archives} 共有文章:[field:c/] 篇 {/d ...

  9. WebApi中添加Jwt鉴权

    前言 JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息.一个 JWT 实际上就是一个字符串,它由三部分组成,头部.载荷与签 ...

  10. node(1)

    1.新建http.js //node搭建http服务器 let http=require('http'); //使用http建立服务请求 http.createServer(function(requ ...