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. 【page cache】回写机制

    目录 writeback 回写 相关结构体 底层设备信息 初始化 部分字段说明 设备回写管理 初始化 部分字段说明 回写任务 部分字段说明 回写线程 初始化 立即唤醒 wb_wakeup wb_que ...

  2. 一台服务器上部署 Redis 伪集群

    哈喽大家好,我是咸鱼 今天这篇文章介绍如何在一台服务器(以 CentOS 7.9 为例)上通过 redis-trib.rb 工具搭建 Redis cluster (三主三从) redis-trib.r ...

  3. QA|如何实现一个函数读取1-9按钮?|网页计算器自动化测试实战

    如何实现一个函数读取1-9按钮? 如何实现一个根据我们Json存的数字,自动选取对应按钮点击,并且点击对应算法? 首先我们肯定不能给每个元素都写一个函数吧,毕竟挺多,而且如果这样写了,那加减乘除都要分 ...

  4. 重磅| Falcon 180B 正式在 Hugging Face Hub 上发布!

    引言 我们很高兴地宣布由 Technology Innovation Institute (TII) 训练的开源大模型 Falcon 180B 登陆 Hugging Face! Falcon 180B ...

  5. 使用KRPano资源分析工具强力加密JS文件

    本文地址:http://www.cnblogs.com/reachteam/p/6294767.html 软件交流群:571171251(软件免费版本在群内提供) krpano技术交流群:551278 ...

  6. Solution Set -「ABC 193」

    「ABC 193A」Discount Link. 略. #include<cstdio> int main() { int a,b; scanf("%d %d",&am ...

  7. Python网络编程——操作系统基础、网络通信原理、.网络通信实现、DNS域名解析、 网络通信流程

    文章目录 一.操作系统基础 二.网络通信原理 2.1 互联网的本质就是一系列的网络协议 2.2 osi七层协议 2.3 tcp/ip五层模型讲解 2.3.1 物理层 2.3.2 数据链路层 2.3.3 ...

  8. Langchain-Chatchat项目:1-整体介绍

      基于Langchain与ChatGLM等语言模型的本地知识库问答应用实现.项目中默认LLM模型改为THUDM/chatglm2-6b[2],默认Embedding模型改为moka-ai/m3e-b ...

  9. Java多线程笔记全过程(一)

    一.多线程最基础的基本概念 一个程序最少需要一个进程,而一个进程最少需要一个线程. 我们常说的高并发,也并不全是线程级别的并发,在很多开发语言中,比如PHP,很常见的都是进程级别的并发.但是在Java ...

  10. go defer简介

    思考 开始之前,先考虑下下面的代码的执行结果: package main import "fmt" func test() int { i := 0 defer func() { ...