和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;
}