标签:
huyichen和xuzhenyi在玩一个游戏:他写一个由0和1组成的序列。
huyichen选其中的一段(比如第3位到第5位),问他这段里面有奇数个1
还是偶数个1。xuzhenyi回答你的问题,然后huyichen继续问。
xuzhenyi有可能在撒谎。huyichen要检查xuzhenyi的答案,指出在xuzhenyi的第几个回答一定有问题。
有问题的意思就是存在一个01序列满足这个回答前的所有回答,而且不存在序列
满足这个回答前的所有回答及这个回答。
第1行一个整数,是这个01序列的长度(<=1000000000)
第2行一个整数,是问题和答案的个数。
第3行开始是问题和答案,
每行先有两个整数,表示你询问的段的开始位置和结束位置。
然后是xuzhenyi的回答。odd表示有奇数个1,even表示有偶数个1。
输出一行,一个数X,表示存在一个01序列满足第1到第X个回答,
但是不存在序列满足第1到第X+1个回答。如果所有回答都没问题,你就输出
所有回答的个数。
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
输出
3
思路:l r even 等价于0-l-1与0-R的序列奇偶性相同。odd等价于奇偶性相反。对x进行hash时,其在hash数组中的位置表示其hash值。
#include<cstdio> #include<cstring> using namespace std; const int MOD=1000007; int Hash[MOD]; int par[MOD+MOD]; int HASH(int x) { int t=x%MOD; while(Hash[t]!=-1&&Hash[t]!=x) t=(t+1)%MOD; Hash[t]=x; return t; } void prep() { for(int i=0;i<MOD+MOD;i++) { par[i]=i; } } int fnd(int x) { if(x==par[x]) return x; return par[x]=fnd(par[x]); } void unite(int x,int y) { int a=fnd(x); int b=fnd(y); par[a]=b; } bool same(int x,int y) { return fnd(x)==fnd(y); } int main() { memset(Hash,-1,sizeof(Hash)); int n,m; scanf("%d%d",&n,&m); int res=m; prep(); for(int i=0;i<m;i++) { int l,r; char s[5]; scanf("%d%d%s",&l,&r,s); if(res!=m) continue; int a=HASH(l-1); int b=HASH(r); if(s[0]==‘e‘) { if(same(a,b+MOD)) { res=i; } unite(a,b); unite(a+MOD,b+MOD); } else { if(same(a,b)) { res=i; } unite(a,b+MOD); unite(a+MOD,b); } } printf("%d\n",res); return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5361692.html