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>
- 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 type[MAXQ], v1[MAXQ], v2[MAXQ], comple[MAXQ];
- int *u[MAXQ];
- int k[MAXQ];
- vector<int> graph[MAXN];
- int visited[MAXN], component[MAXN], size[MAXN];
- int counter = 1;
- void dfs(int start, int v, stack<Action> &stack) {
- visited[v] = counter;
- stack.push(Action(&component[v], component[v]));
- component[v] = start;
- if (v != start) {
- stack.push(Action(&size[start], size[start]));
- size[start] += size[v];
- }
- int sz = graph[v].size();
- for (int i = 0; i < sz; i++) {
- int e = graph[v][i];
- if (visited[e] != counter) {
- dfs(start, e, stack);
- }
- }
- }
- inline void addEdge(int from, int to) {
- graph[from].push_back(to);
- graph[to].push_back(from);
- }
- inline void undoAll(stack<Action> &stack) {
- while (stack.size() > 0) {
- stack.top().undo();
- stack.pop();
- }
- }
- int n, q;
- stack<Action> stacks[25];
- queue<int> queues[25];
- int level = -1;
- void decompose(int l, int r) {
- level++;
- /*
- cout << l << " " << r << endl;
- for (int i = 0; i < n; i++) {
- cout << component[i] << " ";
- }
- cout << endl;
- for (int i = 0; i < n; i++) {
- cout << size[i] << " ";
- }
- cout << endl;
- cout << endl;
- */
- if (l == r) {
- if (type[l] == 3) {
- vector<int> sorted(k[l]);
- copy(u[l], u[l] + k[l], sorted.begin());
- 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 += size[sorted[i]];
- i = j;
- }
- if (sumsize == len) {
- puts("YES");
- } else {
- puts("NO");
- }
- }
- } else {
- int m = (l + r) / 2;
- stack<Action> &stack = stacks[level];
- queue<int> &q = queues[level];
- for (int i = m + 1; i <= r; i++) {
- if (type[i] == 2 && comple[i] < l) {
- int from = v1[comple[i]], to = v2[comple[i]];
- addEdge(from, to);
- q.push(from);
- q.push(to);
- }
- }
- counter++;
- while (q.size() > 0) {
- int v = q.front();
- q.pop();
- if (visited[v] != counter) {
- dfs(v, v, stack);
- }
- graph[v].clear();
- }
- for (int i = l; i <= m; i++) {
- if (type[i] == 1) {
- if (v1[i] != component[v1[i]]) {
- stack.push(Action(&v1[i], v1[i]));
- v1[i] = component[v1[i]];
- }
- if (v2[i] != component[v2[i]]) {
- stack.push(Action(&v2[i], v2[i]));
- v2[i] = component[v2[i]];
- }
- } else if (type[i] == 2) {
- int ii = comple[i];
- if (ii < l) {
- if (v1[ii] != component[v1[ii]]) {
- stack.push(Action(&v1[ii], v1[ii]));
- v1[ii] = component[v1[ii]];
- }
- if (v2[ii] != component[v2[ii]]) {
- stack.push(Action(&v2[ii], v2[ii]));
- v2[ii] = component[v2[ii]];
- }
- }
- } else {
- int len = k[i];
- for (int j = 0; j < len; j++) {
- if (u[i][j] != component[u[i][j]]) {
- stack.push(Action(&u[i][j], u[i][j]));
- u[i][j] = component[u[i][j]];
- }
- }
- }
- }
- 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];
- addEdge(from, to);
- q.push(from);
- q.push(to);
- }
- }
- counter++;
- while (q.size() > 0) {
- int v = q.front();
- q.pop();
- if (visited[v] != counter) {
- dfs(v, v, stack);
- }
- graph[v].clear();
- }
- for (int i = m + 1; i <= r; i++) {
- if (type[i] == 1) {
- if (v1[i] != component[v1[i]]) {
- stack.push(Action(&v1[i], v1[i]));
- v1[i] = component[v1[i]];
- }
- if (v2[i] != component[v2[i]]) {
- stack.push(Action(&v2[i], v2[i]));
- v2[i] = component[v2[i]];
- }
- } else if (type[i] == 2) {
- int ii = comple[i];
- if (ii <= m) {
- if (v1[ii] != component[v1[ii]]) {
- stack.push(Action(&v1[ii], v1[ii]));
- v1[ii] = component[v1[ii]];
- }
- if (v2[ii] != component[v2[ii]]) {
- stack.push(Action(&v2[ii], v2[ii]));
- v2[ii] = component[v2[ii]];
- }
- }
- } else {
- int len = k[i];
- for (int j = 0; j < len; j++) {
- if (u[i][j] != component[u[i][j]]) {
- stack.push(Action(&u[i][j], u[i][j]));
- u[i][j] = component[u[i][j]];
- }
- }
- }
- }
- 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++) {
- visited[i] = 0;
- component[i] = i;
- size[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