[Gym 100228] Graph of Inversions

题意

  给定长度为 $n$ 的序列 $A = \left\{ a_1, a_2, ..., a_n \right\}$ .

  我们定义其逆序图 $G$ : 对于 $i < j$ , $i, j$ 之间存在连边 $\Leftrightarrow a_i > a_j$ .

  给定一个序列的逆序图, 求有多少个点集 $S$ , 满足 $S$ 既是独立集, 又是覆盖集.

  $n \le 1000$ .

分析

  我们考虑探究逆序图与原序列的关系.

  点集 $S$ 在逆序图中是独立集, 当且仅当在原序列中单调不降.

  点集 $S$ 在逆序图中是覆盖集, 当且仅当对于任意相邻的 $i, j$ , $i < j$ , 满足 $\forall k \in (i, j), a_i > a_k 或 a_k > a_j$ .

  我们考虑进行DP.

  可以利用单调性优化到 $O(n ^ 2)$ , 判定 $j$ 是否合法的时间复杂度为 $O(1)$ .

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 #define P(i, a, b) for (register int i = (a); i >= (b); i--)
 7 #define LL long long
 8 inline int rd(void) {
 9     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1;
10     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f;
11 }
12
13 const int N = 1005;
14
15 int n, m;
16 bool g[N][N];
17
18 LL f[N];
19 LL res;
20
21 int main(void) {
22     #ifndef ONLINE_JUDGE
23         freopen("100228.in", "r", stdin);
24     #endif
25
26     n = rd(), m = rd();
27     F(i, 1, m) {
28         int x = rd()+1, y = rd()+1;
29         g[x][y] = g[y][x] = true;
30     }
31     F(i, 0, n+1) g[i][n+1] = g[n+1][i] = true;
32
33     f[0] = 1;
34     F(i, 1, n) {
35         int w = n+1;
36         P(j, i-1, 0)
37             if (!g[j][i] && g[j][w])
38                 f[i] += f[j], w = j;
39     }
40     int w = n+1;
41     for (int j = n; j >= 1; j--)
42         if (g[j][w])
43             res += f[j], w = j;
44     printf("%lld\n", res);
45
46     return 0;
47 }
时间: 2024-08-04 06:28:00

[Gym 100228] Graph of Inversions的相关文章

CodeForces Gym 100228 Graph of Inversions

题目大意 对于一个长为$N$的序列$A$,定义它所对应的逆序图: 有$N$个点组成,标号为$1...N$的无向图,对于每一组$i,j(i<j)$若存在$A_i>A_j$则在新图中就存在一条$(A_i,A_j)$的无向边. 现在给定一个$N(N\leq 1000)$个点的图,保证它是某个序列对应的逆序图,求它有多少个点集$S$,满足$\forall x\in S,y\in S$不存在边$(x,y)$,$\forall x\notin S$至少存在一条边$(x,y)$使得$y\in S$.即求图独

【CF Gym100228】Graph of Inversions

Portal --> qwq(貌似是CodeForces Gym 100228 (ECNA2003) - I) Description 对于长度为 \(n\) 的序列 \(A\) ,定义其逆序图 \(G\) 如下:无向图 \(G\)有\(n\) 个节点,编号为 \(0..n-1\) :对于任意的$ 0≤i<j≤n?1$ ,如果有 \(a[i]>a[j]\),那么 \(G\)中存在一条 \(i\)和 \(j\)之间的边.例如:\(A=\{1,3,4,0,2\}, G=\{(0,3),(1,

Gym 100801G Graph 拓扑排序

http://codeforces.com/gym/100801/attachments 用set维护一下入度为零的点,每次将当前指针和下一个指针连一条边 写博客只是为了纪念一下第一次用set,还有我逝去的4小时青春 PS.iterator在迭代器中不要xjb改 #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #

Gym - 100801G: Graph (贪心+set+拓扑)(好题)

题意:给定一个N点M边的有向图,叫你加最多K条边,使得最小拓扑序最大. 思路:不是那么简单的题.  参照了别人的代码,最后想通了. 贪心原则: 用两个单调队列维护, 第一个序列S1单增, 表示当前入度为0的点 ; 第二个序列S2单减,表示需要加边的点. 如果S1的最大值大于S2的最大值,则对其加边. #include<bits/stdc++.h> using namespace std; const int maxn=100010; priority_queue<int>p; pr

GYM - 100814 C.Connecting Graph

题意: 初始有n个点,m次操作.每次操作加一条边或者询问两个点第一次连通的时刻(若不连通输出-1). 题解: 用并查集维护每个点所在连通块的根.对于每次加边,暴力的更新新的根. 每次将2个块合并时,将小的块并向大的块.这么合并使得每个点的根最多更新log2n次,并储存每次更新信息(更新时刻以及新的根). 对于每一次询问,二分两个点第一次连通的时刻.对于每一个二分的时刻,求的是两点的根是否相同. 由于存储过了每个点根的更新信息,所以再用二分求出他这个时刻的根. #include <bits/std

Codeforces Gym 100342H Problem H. Hard Test 构造题,卡迪杰斯特拉

Problem H. Hard TestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/attachments Description Andrew is having a hard time preparing his 239-th contest for Petrozavodsk. This time the solution to the problem is based on Di

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

CodeForces Gym 100935D Enormous Carpet 快速幂取模

Enormous Carpet Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 100935D Description standard input/outputStatements Ameer is an upcoming and pretty talented problem solver who loves to solve problems using computers.

PAT 1009. Triple Inversions (35) 数状数组

Given a list of N integers A1, A2, A3,...AN, there's a famous problem to count the number of inversions in it. An inversion is defined as a pair of indices i < j such that Ai > Aj. Now we have a new challenging problem. You are supposed to count the