Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <iostream>
- #include <algorithm>
- #include <cstring>
- #include <bitset>
- #include <vector>
- #include <string>
- #include <cmath>
- #include <map>
- using namespace std;
- typedef pair<int, int> ii;
- #define X first
- #define Y second
- #define PB push_back
- #define REP(i, n) for(int i=0; i<(int) (n); i++)
- const int N = 110000;
- int par[N], rank[N];
- bitset<N> hasP, hasR;
- vector<ii> chgP, chgR;
- struct dsu{
- bool backup;
- void init(int n){
- for(int i=1; i<=n; i++){
- par[i] = i;
- rank[i] = 0;
- }
- backup = 0;
- }
- void restore(){
- REP(i, chgP.size()){
- par[chgP[i].X] = chgP[i].Y;
- hasP[chgP[i].X] = 0;
- }
- chgP.clear();
- REP(i, chgR.size()){
- rank[chgR[i].X] = chgR[i].Y;
- hasR[chgR[i].X] = 0;
- }
- chgR.clear();
- backup = 0;
- }
- int find(int u){
- if(par[u] == u) return u;
- if(backup) return find(par[u]);
- return par[u] = find(par[u]);
- }
- void saveP(int u){
- if(backup && hasP[u] == 0){
- hasP[u] = 1;
- chgP.PB(ii(u, par[u]));
- }
- }
- void join(int u, int v){
- u = find(u);
- v = find(v);
- if(u != v){
- if(rank[u] < rank[v]){
- saveP(u);
- par[u] = v;
- } else if(rank[u] > rank[v]){
- saveP(v);
- par[v] = u;
- } else {
- saveP(u);
- if(backup && hasR[v] == 0){
- hasR[v] = 1;
- chgR.PB(ii(v, rank[v]));
- }
- par[u] = v;
- rank[v]++;
- }
- }
- }
- };
- dsu D;
- int n, Q, b, next[N], cmd[N];
- ii E[N];
- map<ii, int> mp;
- map<ii, pair<int, vector<int> > > ma;
- void MAIN(){
- cin >> n >> Q;
- memset(next, 0xff, sizeof next);
- for(int i=0; i<Q; i++){
- cin >> cmd[i] >> E[i].X >> E[i].Y;
- if(E[i].X > E[i].Y) swap(E[i].X, E[i].Y);
- if(cmd[i] == 1){
- ma[E[i]].Y.PB(i);
- ma[E[i]].X++;
- next[i] = Q;
- }
- else if(cmd[i] == 2){
- map<ii, pair<int, vector<int> > >::iterator it = ma.find(E[i]);
- if(it == ma.end()) continue;
- (it->Y.X)--;
- if(it->Y.X == 0){
- REP(j, (it->Y.Y).size()) next[it->Y.Y[j]] = i-1;
- ma.erase(it);
- }
- }
- }
- b = sqrt(Q);
- for(int i=0; i<Q; i+=b){
- int en = i+b-1;
- vector<int> v[400];
- if(en >= Q) en = Q-1;
- D.init(n);
- REP(j, i) if(next[j] > en) D.join(E[j].X, E[j].Y);
- else if(next[j] >= i) v[next[j]-i].PB(j);
- string s;
- for(int j=en; j>=i; j--){
- REP(l, v[j-i].size()) D.join(E[v[j-i][l]].X, E[v[j-i][l]].Y);
- if(cmd[j] == 3){
- D.backup = 1;
- for(int l=i; l<j; l++) if(next[l] >= j) D.join(E[l].X, E[l].Y);
- if(D.find(E[j].X) == D.find(E[j].Y) ) s += '1';
- else s += '0';
- D.restore();
- }
- }
- reverse(s.begin(), s.end()); cout << s;
- }
- }
- int main(){
- //freopen("input.in", "r", stdin);
- ios::sync_with_stdio(false);
- MAIN();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement