POJ1733解题报告

        这道题其实很早以前就已经做过了,VJ和Tyvj上叫小胖的奇偶,CODEVS上交奇偶游戏,没想到还是1999年的省选题。。CEOI不知道是哪个省。本来我都不打算做了,但是重新做了一遍没想到又有新的收获。
        1、对于整数x,y:
                其模2意义下的值等于其原数&1;
                模2意义下的加减法等价于^.
                模2意义下的乘除法等价于&.
        ------综上,我们可以用位运算来优化这道题。
        2、但,位运算有一个问题!!!:
                    位运算的优先级低于比较运算符。。。
综,这道题让我复习和巩固了位运算的知识和用法。
代码:
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
char * ptr=new char [200000];
typedef short hd;
inline void in(int &x){
while(*ptr<'0'||*ptr>'9')++ptr;
x=0;
while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0';
}
inline void in(short &x){
while(*ptr<'0'||*ptr>'9')++ptr;
x=0;
while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0';
}
inline void in(char &x){
while(*ptr<'a'||*ptr>'z')++ptr;
x=*ptr++;
}
hd fa[10000],tot;
bool d[10000];
inline hd find(hd x){
if(fa[x]!=fa[fa[x]]){
hd ftr=fa[x];
fa[x]=find(fa[x]);
d[x]^=d[ftr];
}
return fa[x];
}
int hash[10000];
inline hd bi(int x){
hd m=tot>>1,l=0,r=tot;
while(hash[m]!=x){
if(hash[m]>x)r=m-1;
else l=m+1;
m=(l+r)>>1;
}
return m;
}
int main(){
hd n,i=-1;
int l,a[5000],b[5000];
char c[5000];
freopen("POJ1733.in","r",stdin);
ptr[fread(ptr,1,199999,stdin)]='z';
in(l);
in(n);
while(++i<n){
in(a[i]);
in(b[i]);
in(c[i]);
if(c[i]=='e')c[i]=0;
else c[i]=1;
hash[tot++]=--a[i];
hash[tot++]=b[i];
}
sort(hash,hash+tot);
tot=unique(hash,hash+tot)-hash;
for(i=1;i<tot;++i)
fa[i]=i;
for(i=0,--tot;i<n;++i){
a[i]=bi(a[i]);
b[i]=bi(b[i]);
}
for(i=0;i<n;++i)
if(find(a[i])!=find(b[i])){
d[fa[a[i]]]=(c[i]+d[b[i]]-d[a[i]])&1;
fa[fa[a[i]]]=fa[b[i]];
}
else
if(((d[a[i]]-d[b[i]])&1)!=c[i])
break;
printf("%hd",i);
}

你可能感兴趣的:(位运算,poj,并查集)