51nod1204 Parity

时间:2022-03-10 10:33:29

如果sm[j]和sm[i]奇偶性相同,那么(i+1,j)个数为偶数
如果奇偶性相同看成是朋友,不同的看成是敌人,那么就跟bzoj1370的做法差不多了。
如果奇偶性相同,就将x和y合并,x+n,y+n合并
如果奇偶性不同,就将x和y+n合并,y和x+n合并

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
const int nmax=2e5+5;
int fa[nmax];
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main(){
int n=read(),m=read(),u,v,ta,tb,tc,td;char ch[10];
rep(i,1,n*2+2) fa[i]=i;
int ans=0;
rep(i,1,m){
u=read()-1,v=read();scanf("%s",ch);
if(ans) continue;
if(ch[0]=='e'){
ta=find(u),tb=find(v),tc=find(u+n+1),td=find(v+n+1);
if(ta==td||tb==tc) ans=i;
else fa[ta]=tb,fa[tc]=td;
}else {
ta=find(u),tb=find(v),tc=find(u+n+1),td=find(v+n+1);
if(ta==tb||tc==td) ans=i;
else fa[ta]=td,fa[tb]=tc;
}
}
if(ans) printf("%d\n",ans);else puts("-1");
return 0;
}

  

题目来源: Ural
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
51nod1204 Parity 收藏
51nod1204 Parity 关注
你的朋友写下一串包含1和0的串让你猜,你可以从中选择一个连续的子串(例如其中的第3到第5个数字)问他,该子串中包含了奇数个还是偶数个1,他会回答你的问题,然后你可以继续提问......你怀疑朋友的答案可能有错,或说同他之前的答案相互矛盾,例如:1 - 2 奇数,3 - 4 奇数,那么可以确定1 - 4 一定是偶数,如果你的朋友回答是奇数,就产生了矛盾。给出所有你朋友的答案,请你找出第一个出现矛盾的答案。
 
Input
第1行:2个数N, Q,N为串的长度,Q为询问的数量。(2 <= N <= 100000, 2 <= Q <= 50000)
第2 - Q + 1行:每行包括两个数以及一个字符串来描述朋友的回答,2个数中间用空格分隔,分别表示区间的起点和终点,后面的字符为"even"或"odd",表示朋友的答案。
Output
输出1个数,表示朋友的答案中第一个错误答案的位置,如果所有答案均不矛盾,则输出-1。
Input示例
10 5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
Output示例
4