Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <stack>
- #include <queue>
- #include <algorithm>
- #include <ctime>
- using namespace std;
- struct Action {
- int *pos;
- int prevval;
- inline Action(int *pos, int prevval) {
- this->pos = pos;
- this->prevval = prevval;
- }
- inline void undo() {
- *pos = prevval;
- }
- };
- const int MAXN = 1111111, MAXQ = 2222222;
- int n, q;
- int type[MAXQ], v1[MAXQ], v2[MAXQ], comple[MAXQ];
- int *u[MAXQ];
- int k[MAXQ];
- int parent[MAXN], sz[MAXN];
- stack<Action> stacks[25];
- int level = -1;
- int findSet(int v) {
- if (parent[v] == v) {
- return v;
- } else {
- return findSet(parent[v]);
- }
- }
- void join(int v1, int v2, stack<Action> &stack) {
- int s1 = findSet(v1), s2 = findSet(v2);
- if (s1 != s2) {
- if (sz[s2] > sz[s1]) {
- swap(s1, s2);
- }
- stack.push(Action(&parent[s2], parent[s2]));
- parent[s2] = s1;
- stack.push(Action(&sz[s1], sz[s1]));
- sz[s1] += sz[s2];
- }
- }
- inline void undoAll(stack<Action> &stack) {
- while (stack.size() > 0) {
- stack.top().undo();
- stack.pop();
- }
- }
- void decompose(int l, int r) {
- level++;
- /*
- cout << l << " " << r << endl;
- for (int i = 0; i < n; i++) {
- cout << findSet(i) << " ";
- }
- cout << endl;
- for (int i = 0; i < n; i++) {
- cout << sz[i] << " ";
- }
- cout << endl;
- cout << endl;
- */
- if (l == r) {
- if (type[l] == 3) {
- vector<int> sorted(k[l]);
- for (int i = 0; i < k[l]; i++) {
- sorted[i] = findSet(u[l][i]);
- }
- sort(sorted.begin(), sorted.end());
- int sumsize = 0;
- int len = sorted.size();
- for (int i = 0; i < len; ) {
- int j = i;
- while (j < len && sorted[j] == sorted[i]) {
- j++;
- }
- sumsize += sz[sorted[i]];
- i = j;
- }
- if (sumsize == len) {
- puts("YES");
- } else {
- puts("NO");
- }
- }
- } else {
- int m = (l + r) / 2;
- stack<Action> &stack = stacks[level];
- if (stack.size() != 0) {
- exit(1);
- }
- for (int i = m + 1; i <= r; i++) {
- if (type[i] == 2 && comple[i] < l) {
- int from = v1[comple[i]], to = v2[comple[i]];
- join(from, to, stack);
- }
- }
- decompose(l, m);
- undoAll(stack);
- for (int i = l; i <= m; i++) {
- if (type[i] == 1 && comple[i] > r) {
- int from = v1[i], to = v2[i];
- join(from, to, stack);
- }
- }
- decompose(m + 1, r);
- undoAll(stack);
- }
- level--;
- }
- int main() {
- //freopen("input.txt", "r", stdin);
- scanf("%d %d", &n, &q);
- for (int i = 0; i < n; i++) {
- parent[i] = i;
- sz[i] = 1;
- }
- vector<int> addTime(q);
- int addCnt = 0;
- for (int i = 0; i < q; i++) {
- scanf("%d", &type[i]);
- if (type[i] == 1) {
- scanf("%d %d", &v1[i], &v2[i]);
- v1[i]--;
- v2[i]--;
- comple[i] = q;
- addTime[addCnt++] = i;
- } else if (type[i] == 2) {
- int m;
- scanf("%d", &m);
- m--;
- comple[i] = addTime[m];
- comple[addTime[m]] = i;
- } else {
- scanf("%d", &k[i]);
- u[i] = new int[k[i]];
- for (int j = 0; j < k[i]; j++) {
- int val;
- scanf("%d", &val);
- val--;
- u[i][j] = val;
- }
- }
- }
- int logq = 0, qc = q;
- while (qc > 1) {
- qc = (qc + 1) / 2;
- logq++;
- }
- decompose(0, q - 1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement