LINK
轉化一下如果
s[l,r]中有偶數個1 那麼sum[r]中的1的奇偶性就和sum[l-1]的奇偶性相同了
傳遞:
x1 x2 奇偶性相同 x2 x3 相同 ->x1 x3同
x1 x2 奇偶性不同 x2 x3不同-> x1 x3 同
…
採用 邊帶權的並查集
d[x] =0 表示x與fa[x]的就相同 ;=1 表示不同
#include<bits/stdc++.h>
using namespace std;
const int N=20010;
struct node
{
int l,r,ans;
}q[N];
int n,m,t;
int fa[N],a[N],d[N];
int find(int x)
{
if(x==fa[x]) return x;
int rt=find(fa[x]) ;
d[x]^=d[fa[x]];
return fa[x]=rt;
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
char s[10];
scanf("%d%d%s",&q[i].l,&q[i].r,s);
q[i].ans=(s[0]=='o'?1:0);
a[++t]=q[i].l -1;
a[++t]=q[i].r ;
}
sort(a+1,a+1+t);
n=unique(a+1,a+1+t)-a-1;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
int x=lower_bound(a+1,a+1+n,q[i].l-1)-a;
int y=lower_bound(a+1,a+1+n,q[i].r )-a;
int xx=find(x),yy=find(y);
if(xx==yy)
{
if(d[x]^d[y]!=q[i].ans )//矛盾輸出
{
printf("%d\n",i-1);return 0;
}
}else
{
fa[yy]=xx;//合併
d[yy]=d[x]^d[y]^q[i].ans;
}
}
printf("%d\n",m);
}
- 拓展域 x表示爲偶數的情況 x+n表示爲奇數的情況
對於 ans =0
x=l-1 y=r 可以得到
sum[x] 爲偶數 sum[y]爲偶數
或者sum[x]爲奇數 sum[y]爲奇數
對於 ans=1
x=l-1y=r 可以得到
sum[x]爲偶數 sum[y]爲奇數
或者sum[x]爲奇數 sum[y]爲偶數
#include<bits/stdc++.h>
using namespace std;
int fa[10001],a[10001];
struct node
{
int l,r,o;
}q[5001];
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int main()
{
int n,m,t=0;scanf("%d%d",&n,&m);
for(int i=1;i<=10000;i++) fa[i]=i;
for(int i=1;i<=m;i++)
{
char s[10];
scanf("%d%d%s",&q[i].l,&q[i].r,s);
q[i].o=s[0]=='o'?1:0;
a[++t]=q[i].l-1;
a[++t]=q[i].r;
}
sort(a+1,a+1+t);
n=unique(a+1,a+1+t)-a-1;
for(int i=1;i<=m;i++)
{
int x=lower_bound(a+1,a+1+n,q[i].l-1)-a;
int y=lower_bound(a+1,a+1+n,q[i].r)-a;
if(q[i].o==0)//奇偶性一致
{
if(find(x)==find(y+n))
{
printf("%d\n",i-1);
return 0;
}
fa[find(x)]=find(y);
fa[find(x+n)]=find(y+n);
}else //奇偶性不一致
{
if(find(x)==find(y))
{
printf("%d\n",i-1);
return 0;
}
fa[find(x+n)]=find(y);
fa[find(x)]=find(y+n);
}
}
printf("%d\n",m);
}