zoukankan      html  css  js  c++  java
  • 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("");
        }
    }
  • 相关阅读:
    Android消息机制(Handler)详述
    Android自定义组件-以饼状图并实现点击事件为例
    Markdown中tab的解析与4个空格 问题
    策略模式(Strategy)
    观察者模式(Observer)
    适配器模式(Adapter Class/Object)
    建造者模式(Builder)
    简单工厂模式、工厂方法模式、抽象工厂模式
    单例模式(Singleton)
    工具推荐:前后端一体化部署,效能提升开源“神器”
  • 原文地址:https://www.cnblogs.com/wmj6/p/11313691.html
Copyright © 2011-2022 走看看