和3237做法差不多,把cdq分治改成在线的就可以了。
至于怎么在线cdq分治?这个只可意会,不可言传。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define maxn 500010 using namespace std; struct yts { int x,y; bool flag; }e[maxn]; int ans[maxn],f[maxn],c[20]; int n,m,k,T; char s[maxn]; int find(int x) { if (x==f[x]) return x; else return f[x]=find(f[x]); } bool check(char x) { return x>='0' && x<='9'; } int cal(int l,int r) { int x=0; for (int i=l;i<=r;i++) x=x*10+s[i]-'0'; return x; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d%d",&e[i].x,&e[i].y); scanf("%d",&T); for (int i=1;i<=T;i++) { int kk,k=0; scanf("%d",&kk); gets(s+1); int len=strlen(s+1); for (int j=1;j<=len;j++) if (check(s[j]) && !check(s[j+1])) k++; ans[i-1]=k^kk; if (i==T) { for (int j=1;j<=len;j++) if (check(s[j])) { int k=j; while (check(s[k])) k++; e[cal(j,k-1)^ans[i-1]].flag=1; j=k-1; } } } for (int i=1;i<T;i++) if (ans[i]-ans[i-1]) printf("Connected\n"); else printf("Disconnected\n"); for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=m;i++) if (!e[i].flag) { int f1=find(e[i].x),f2=find(e[i].y); if (f1!=f2) f[f1]=f2; } int num=f[1]; for (int i=2;i<=n;i++) if (f[i]!=num) {printf("Disconnected\n");return 0;} printf("Connected\n"); return 0; }