Parity game-- Weighted disjoint-set

Topic Link

Meaning of the questions:

You a string of 0's and 1's, and tell you the number of substring inside the 1, and assume that the words are right, and ask you where a previous contradictory words.

answer:

First, find n great, but the problem is the number of m much, so the first discrete

d represents sequence S prefix array and
d [l ~ r] has an even number of 1, equivalent to the d [l-1] and d [R & lt] have the same parity.

d [l ~ r] has an odd number 1, is equivalent to d [l-1] and d [r] different parity.

 

Is then passed through an exclusive OR to satisfy the above relations i.e. the same parity is an even parity XOR exclusive or different odd

Combined with the method set  How Many Answers Are Wrong  similar

d [i] represents 1 to i and, if present [i, a] and [i, b] is determined as long as [b, i] [^ a-1, i] to parity

 

Therefore, maintaining a common point disjoint-set root node (actually d [i] can be regarded as the root node to the i distance)

So how to merge the collection?

Let fx fy directed i.e.  f [fy] = fx;     as  d [fx] ^ d [x   ] ^ d [y] = a [i] .ans so  d [fx] ^ d [x ] ^ d [y] = a [i] .ans

 

Code:

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7;
vector<int>v;
int f[maxn],d[maxn];
int get_id(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
struct node
{
    int l,r,ans;
} a[maxn];
int Find(int x)
{
    if(f[x]==x)return x;
    int root=Find(f[x]);
    d[x]^=d[f[x]];
    return f[x]=root;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        char str[10];
        scanf("%d%d%s",&a[i].l,&a[i].r,str);
        v.push_back(a[i].l-1);
        v.push_back(a[i].r);
        a[i].ans=(str[0]=='e'?0:1);
    }
    sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());
    for(int i=1; i<=v.size(); i++)f[i]=i,d[i]=0;
    int res=m;
    for(int i=1; i<=m; i++)
    {
        int x=get_id(a[i].l-1);
        int y=get_id(a[i].r);
        int fx=Find(x);
        int fy=Find(y);
        if(fx==fy)
        {
            if((d[x]^d[y])!=a[i].ans)
            {
                res=i-1;
                break;
            }
        }
        else
        {
            f[fx]=fy;
            d[fx]^=d[x]^d[y]^a[i].ans; ///  d[fx]^d[x]^d[y]=a[i].ans
        }
    }
    printf("%d\n",res);


    return 0;
}
View Code

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/j666/p/11615302.html