http://codeforces.com/contest/566/problem/D
Even the most successful company can go through a crisis period when you have to make a hard decision — to restructure, discard and merge departments, fire employees and do other unpleasant stuff. Let's consider the following model of a company.
There are n people working for the Large Software Company. Each person belongs to somedepartment. Initially, each person works on his own project in his own department (thus, each company initially consists of n departments, one person in each).
However, harsh times have come to the company and the management had to hire a crisis manager who would rebuild the working process in order to boost efficiency. Let's useteam(person) to represent a team where person person works. A crisis manager can make decisions of two types:
- Merge departments team(x) and team(y) into one large department containing all the employees of team(x) and team(y), where x and y (1 ≤ x, y ≤ n) — are numbers of two of some company employees. If team(x) matches team(y), then nothing happens.
- Merge departments team(x), team(x + 1), ..., team(y), where x and y (1 ≤ x ≤ y ≤ n) — the numbers of some two employees of the company.
At that the crisis manager can sometimes wonder whether employees x and y (1 ≤ x, y ≤ n) work at the same department.
Help the crisis manager and answer all of his queries.
The first line of the input contains two integers n and q (1 ≤ n ≤ 200 000, 1 ≤ q ≤ 500 000) — the number of the employees of the company and the number of queries the crisis manager has.
Next q lines contain the queries of the crisis manager. Each query looks like type x y, where . If type = 1 or type = 2, then the query represents the decision of a crisis manager about merging departments of the first and second types respectively. If type = 3, then your task is to determine whether employees x and y work at the same department. Note that x can be equal to y in the query of any type.
For each question of type 3 print "YES" or "NO" (without the quotes), depending on whether the corresponding people work in the same department.
最麻烦就是第2种情况了,合并一个区间。
但是合并一次过后,它就是属于同一个组了,那么可以设tonext[i]表示第i个人所属的组,的下一个组,就是下一个和它合并的组。
开始的时候tonext[i] = i + 1
那么如果合并[x, y]区间,首先合并x和tonext[x],然后合并tonext[x] 和 tonext[tonext[x]]
那么回溯的时候顺便更新个tonext,以后合并就是跳着合并了,不会一个个暴力合并。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 200000 + 20; int fa[maxn]; int tonext[maxn]; int tofind(int x) { if (fa[x] == x) return x; else return fa[x] = tofind(fa[x]); } void tomerge(int u, int v) { u = tofind(u); v = tofind(v); fa[v] = u; } void dfs(int be, int en, int cur, int pre) { if (cur > en) { tonext[pre] = cur; return; } tomerge(pre, cur); dfs(be, en, tonext[cur], cur); tonext[pre] = tonext[cur]; } void work() { int n, q; scanf("%d%d", &n, &q); for (int i = 1; i <= n; ++i) { fa[i] = i; tonext[i] = i + 1; } for (int i = 1; i <= q; ++i) { int op, x, y; scanf("%d%d%d", &op, &x, &y); if (op == 1) { tomerge(x, y); } else if (op == 2) { dfs(x, y, tonext[x], x); } else { if (tofind(x) == tofind(y)) { printf("YES "); } else printf("NO "); } } } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }