Timus 1003. Parity 【并查集】

来源:互联网 发布:淘宝four loko是真的嘛 编辑:程序博客网 时间:2024/06/05 16:01

传送门


输入的询问可能=0
巨坑…..因此re一晚上


sum[j]=ji=0a[i]   (mod2)
sum[a]=sum[b]sum[b]=sum[c]sum[a]=sum[b]=sum[c]
便2,sum[x]=1sum[y]=0

[i,j],sum[j]sum[i1]=0  (mod 2)
find(i1)==find(j)

[i,j],sum[j]sum[i1]=1  (mod 2)
maxVal=n
sum[x+maxVal]!=sum[x]
[i,j],ji1+maxVali1,j

#include<stdio.h>#include<bits/stdc++.h>#define ll long long#define pii pair<int,int>#define pll pair<ll,ll>#define MEM(a,x) memset(a,x,sizeof(a))#define lowbit(x) ((x)&-(x))using namespace std;const int inf = 1e9+7;const int N = 5e3 + 50;const int M = 10*N+50;char str[10];struct data{    int s,t;    bool odd;}ask[N];int discr(int n){//离散化 返回最大值    map<int,int>mp;    for(int i=0;i<n;++i){        mp[ask[i].s]=0;        mp[ask[i].t]=0;        mp[ask[i].s-1]=0;    }    int j=1;    for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){        it->second=j++;    }    for(int i=0;i<n;++i){        ask[i].s=mp[ask[i].s];        ask[i].t=mp[ask[i].t];    }    return mp.empty()?1:mp.rbegin()->second;//若不判空集,询问为0时re}struct Union{//并查集    int par[M];    void init(int n){        for(int i=0;i<n;++i){            par[i]=i;        }    }    int find(int x){        return x==par[x]?x:(par[x]=find(par[x]));    }    void merge(int x,int y){        x=find(x);        y=find(y);        par[y]=x;    }}un;int slove(int n){    int maxVal=discr(n);    un.init(2*maxVal+1);    int ans=0;//可能询问为0,初始ans=0    for(int i=0;i<n;++i){        int x=ask[i].s-1;        int y=ask[i].t;        if(ask[i].odd){            if(un.find(x)==un.find(y)){                break;            }            else{                un.merge(x+maxVal,y);                un.merge(y+maxVal,x);            }        }        else{            if(un.find(x+maxVal)==un.find(y)){                break;            }            else{                un.merge(x,y);                un.merge(x+maxVal,y+maxVal);            }        }        ans=i+1;    }    return ans;}int main(){    //freopen("/home/lu/code/r.txt","r",stdin);    //freopen("/home/lu/code/w.txt","w",stdout);    int n,k;    while(~scanf("%d",&k)&&k!=-1){        scanf("%d",&n);        for(int i=0;i<n;++i){            scanf("%d%d%s",&ask[i].s,&ask[i].t,str);            ask[i].odd=(str[0]=='o');        }        printf("%d\n",slove(n));    }    return 0;}