如果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 ",ans);else puts("-1"); return 0; }
收藏
关注
你的朋友写下一串包含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