提交时间:2024-01-13 20:02:02
运行 ID: 24913
#include <iostream> #include <cstdio> #include <math.h> #include <algorithm> #include <istream> #include <string> #include <queue> #include <deque> #include <random> #include <stack> #include <set> #include <string.h> #include <map> #include <unordered_map> #include <sstream> #include <bitset> #include <fstream> #include <climits> #include <time.h> #include <cassert> using namespace std; #define int long long #define double long double #define endl "\n" #define pii pair<int,int> #define p1(x) ((x).first) #define p2(x) ((x).second) int n,q,m,cnt; map<pii,int>id; map<int,int>nxt[100030],us[100300]; pii e[1000300]; vector<int>g[100300]; int ud[1000030],vd[1000300]; inline void add(int i,int x){ if(ud[i])vd[i]=x; else ud[i]=x; } int f[1000030]; int res=1; int eid[2003000]; int ev[2003000]; int hd[100300]; int enxt[2003000]; inline int ff(int x){ return f[x]==x?x:f[x]=ff(f[x]); } int ecnt; inline void add_edge(int u,int id){ ++ecnt; enxt[ecnt]=hd[u]; eid[ecnt]=id; ev[ecnt]=p1(e[id])+p2(e[id])-u; hd[u]=ecnt; } int D[100300]; inline void updu(int u){ while(hd[u]&&D[eid[hd[u]]]) hd[u]=enxt[hd[u]]; } inline void upde(int eloc){ while(enxt[eloc]&&D[eid[enxt[eloc]]]) enxt[eloc]=enxt[enxt[eloc]]; } inline bool merge(int x,int y){ x=ff(x),y=ff(y); if(x==y)return 1; f[x]=y; return 0; } inline bool del(int id){ if(D[id])return 0; D[id]=1; bool r=0; res+=r=merge(ud[id],vd[id]); return r; } int cb; int bel[100300]; bool ins[100300]; signed main(){ ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); cin>>n>>q; for(int i=1;i<=n;i++){ int k; cin>>k; while(k--){ int x=i,y; cin>>y; if(!id[{x,y}]){ id[{x,y}]=++m; id[{y,x}]=m; e[m]={x,y}; } g[i].push_back(id[{x,y}]); add_edge(i,id[{x,y}]); } } //dfs(1,0); for(int u=1;u<=n;u++){ int lst=g[u].back(); for(int x:g[u]){ nxt[u][lst]=x; lst=x; } } for(int u=1;u<=n;u++) for(int id:g[u])if(!us[u][id]){ int x=id,y=u; ++cnt; f[cnt]=cnt; while(!us[y][x]){ us[y][x]=1; add(x,cnt); y=p1(e[x])+p2(e[x])-y; x=nxt[y][x]; } } int lst=0; while(q--){ char op; int x,y; cin>>op>>x>>y; x^=lst,y^=lst; //cout<<op<<" "<<x<<" "<<y<<endl; if(op=='-'){ int ID=id[{x,y}]; if(del(ID)){ ++cb; vector<int>U,V; deque<int>qu,qv; updu(x); updu(y); if(hd[x]) qu.push_back(hd[x]); if(hd[y]) qv.push_back(hd[y]); U.push_back(x); V.push_back(y); ins[x]=ins[y]=1; while(1){ if(qv.empty()){ for(int u:U) ins[u]=0; for(int v:V) ins[v]=0,bel[v]=cb; break; } if(qu.empty()){ for(int u:U) ins[u]=0,bel[u]=cb; for(int v:V) ins[v]=0; break; } int u=qu.front(); qu.pop_front(); int v=qv.front(); qv.pop_front(); upde(u); upde(v); if(enxt[u])qu.push_front(enxt[u]); if(enxt[v])qv.push_front(enxt[v]); int nu=ev[u],nv=ev[v]; if(!ins[nu]){ ins[nu]=1; updu(nu); if(hd[nu])qu.push_back(hd[nu]); U.push_back(nu); } if(!ins[nv]){ ins[nv]=1; updu(nv); if(hd[nv])qu.push_back(hd[nv]); V.push_back(nv); } } } cout<<(lst=res)<<endl; } else cout<<(lst=(bel[x]==bel[y]))<<endl; } cout.flush(); return 0; } /* */