zoukankan      html  css  js  c++  java
  • 【奇偶传递 扩展域】 奇偶游戏

    传送门

    题意

    给定一个(N)表示一个(01)序列(S)的长度,给定(M)个指示,每个指示一个(l、r),以及说明关系的字符串

    • ((l,r,odd)),表示((l,r))有偶数个(1)
    • ((l,r,even)),表示((l,r))有奇数个(1)

    求出在多少个指示后出现矛盾

    数据范围

    (N leq 10^{9}, M leq 10000)

    题解

    将每个给定的都看作是条件,同样用到前缀和,(x)表示(l-1)(y)表示 (r)

    • 如果有偶数个,合并(x_{odd})(y_{odd})(x_{even})(y_{even}),说明(x)为奇数和(y)为奇数可以互相推出,(x)为偶和(y)为偶也可以互相推出。

    • 如果有奇数个,那么合并(x_{odd})(y_{even})(x_{even})(y_{odd}),说明(x)为奇数和(y)为偶数可以互相推出,(x)为偶和(y)为奇也可以互相推出。

    相当于在无向图中维护连通性关系,满足传递性,(l)的奇数域即离散化后的自身,偶数域表示为将(l+N)后离散化的值,(r)同理

    • 因为一次性合并两个域名,所以只需要判断其中一个即可

      • (l)(r)的奇偶性不同时,如果(x_{odd} = y_{odd})(x_{even} =y_{even}) 即矛盾

      • 当奇偶性相同时,如果(x_{odd} = y_{even})(x_{even}=y_{odd})时矛盾

    Code

    #include<bits/stdc++.h>
    using namespace std;
    
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    
    const int N=1e5+10;
    
    
    int fa[N*2];
    int n,m,cnt;
    unordered_map<int,int> rec;
    
    int find(int x)
    {
        if(fa[x]!=x) fa[x]=find(fa[x]);
        return fa[x];
    }
    
    void merge(int a,int b)
    {
        int pa=find(a),pb=find(b);
        if(pa!=pb)
        {
            fa[pa]=pb;
        }
    }
    int disperse(int x)
    {
        if(!rec[x]) rec[x]=++cnt;
        return rec[x];
    }
    int main()
    {
        cin>>n>>m;
        rep(i,0,N*2+1) fa[i]=i;
        char op[5];int l,r;
        int diff;
    
        rep(i,1,m+1)
        {
            cin>>l>>r>>op;
            l=disperse(l-1),r=disperse(r);
            int lodd=l,leven=disperse(l+n),rodd=r,reven=disperse(r+n);
            if(op[0]=='e') diff=0;
            else diff=1;
            if(diff)
            {
                if(find(lodd) == find(rodd))
                {
                    cout<<i-1<<endl;
                    return 0;
                }
                merge(lodd,reven);merge(leven,rodd);
            }
            else 
            {
                if(find(lodd)==find(reven))
                {
                    cout<<i-1<<endl;
                    return 0;
                }
                merge(lodd,rodd);merge(leven,reven);
            }
        }
        cout<<m<<endl;
    }
    
  • 相关阅读:
    mac github访问不稳定解决办法
    前后端项目部署-2, flask+Gunicorn+gevent,docker部署,
    前后端项目部署-1, flask,只有flask,一个最简单的flask项目部署到Docker的过程,
    mac,VMware,安装centos7,虚拟机,无界面
    深网简介
    mitmproxy抓包工具使用 for mac
    安卓抓取的另外一种思路
    安卓手机设置权限,adb pull permission denied解决办法
    爬虫工程师到底为什么要学习安卓逆向?
    爬虫工程师日常都是做什么。
  • 原文地址:https://www.cnblogs.com/hhyx/p/13756782.html
Copyright © 2011-2022 走看看