2019牛客暑期多校训练营(第三场)A.Graph Games (分块)

题意:给你n个点 m条边的一张图 现在有q次操作 每次操作可以选择反转l~r的边号 也可以询问S(l)和S(r) 连接成的点集是否相同

思路:我们把m条边分块 用一个S数组维护每块对一个点的贡献 然后块间打标记 两端暴力

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 2e5+7,M = 505;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef unsigned long long ll;
const ll mod = 1e7+9;
int L[M],R[M],block[N],lazy[M];
ll Hash[N],val[N],S[M][N];
int a[N],b[N];
int n,m;
int main(){
//    ios::sync_with_stdio(false);
//    cin.tie(0); cout.tie(0);
    int T; scanf("%d",&T);
    srand(unsigned(time(NULL)));
    for(int i=0;i<N;i++)
        Hash[i]=rand();
    while(T--){
        scanf("%d%d",&n,&m);
        int t=sqrt(m);
        for(int i=1;i<=m;i++){
            block[i]=(i+t-1)/t;
        }
        for(int i=1;i<=(m+t-1)/t;i++){
            L[i]=(i-1)*t+1; R[i]=min(m,i*t);
            for(int j=1;j<=n;j++)
                S[i][j]=0;
            lazy[i]=0;
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a[i],&b[i]);;
            S[block[i]][a[i]]^=Hash[b[i]];
            S[block[i]][b[i]]^=Hash[a[i]];
        }
        int qq; scanf("%d",&qq);
        for(int i=1;i<=qq;i++){
            int op,l,r; scanf("%d",&op);
            if(op==1){
                scanf("%d%d",&l,&r);
                int p=block[l]; int q=block[r];
                if(p==q){
                    for(int i=l;i<=r;i++)
                        val[a[i]]^=Hash[b[i]],val[b[i]]^=Hash[a[i]];
                }else{
                    for(int i=1;i<=R[p];i++)
                        val[a[i]]^=Hash[b[i]],val[b[i]]^=Hash[a[i]];
                    for(int i=p+1;i<=q-1;i++)
                        lazy[i]^=1;
                    for(int i=L[q];i<=r;i++)
                        val[a[i]]^=Hash[b[i]],val[b[i]]^=Hash[a[i]];
                }
            }else{
                scanf("%d%d",&l,&r);
                ll sa=val[l]; ll sb=val[r];
                for(int i=1;i<=(m+t-1)/t;i++)
                    if(!lazy[i])
                sa^=S[i][l],sb^=S[i][r];
                printf("%d",(sa==sb));
            }
        }
        puts("");
    }
}

 

posted @ 2019-08-07 10:26  WAKBGAN  阅读(193)  评论(0编辑  收藏  举报