• 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("");
        }
    }
  • 相关阅读:
    分段和分页内存管理
    从文件/文件流的头字节中得到mime信息
    selenium中WebElement.getText()为空解决方法
    29个酷炫的Firefox配置参数
    web automation 常用技术比较
    误判心理学
    区块链+金融,带你直击实践应用中的需求和痛点
    供应链金融平台
    供应链金融的三种模式和四大趋势
    中国的支付清算体系是怎么玩的?
  • 原文地址:https://www.cnblogs.com/wmj6/p/11313691.html
Copyright © 2020-2023  润新知