HDU 3234 Exclusive-OR
AC代码
#include <algorithm>
#include <cstring>
#include <sstream>
using namespace std;
typedef long long ll;
const int N = 5e5 + 4;
int f[N],ans[N],a[1000],n,m;
bool dis[1000];
int read_list(int *a);
void ini(int n);
int find(int u)
{
if(u==f[u])return u;
int t=f[u];
f[u]=find(f[u]);
ans[u]^=ans[t];
return f[u];
}
bool unit(int x,int y,int z)
{
int a=find(x),b=find(y);
if(a==b)return ((ans[x]^ans[y])!=z);
if(a==n)swap(a,b);
f[a]=b;
ans[a]=ans[x]^ans[y]^z;
return 0;
}
bool Q(int len,int *a,int &an)
{
int x[2],idx=0;
for(int i=1;i<len;i++)dis[i]=0;
for(int i=1;i<len;i++)
{
if(dis[i])continue;
int t=find(a[i]);
for(int j=i;j<len;j++)
{
if(find(a[j])==t)dis[j]=1,x[idx++]=a[j];
if(idx==2)an^=ans[x[0]]^ans[x[1]],idx=0;
}
if(idx==1)
{if(find(x[0])!=n)return 1;
else an^=ans[x[0]];idx=0;}
}
return 0;
}
int main() {
int TESTnum=1;
while(scanf("%d%d",&n,&m),n&&m)
{
printf("Case %d:\n",TESTnum++);
char op[2];
int Inum=0,flag=0,q;
ini(n);
while(m--)
{
scanf("%s",op);
int len=read_list(a),an=0;
if(flag)continue;
if(op[0]=='I')
{
Inum++;
if(len==2)q=unit(a[0],n,a[1]);
else q=unit(a[0],a[1],a[2]);
if(q)printf("The first %d facts are conflicting.\n",Inum),flag=1;
}
else
{
if(Q(len,a,an))puts("I don't know.");
else printf("%d\n",an);
}
}
puts("");
}
return 0;
}
int read_list(int *a)
{
string line;
if(!getline(cin,line))return false;
stringstream ss(line);
int n=0,x;
while(ss>>x)a[n++]=x;
return n;
}
void ini(int n)
{for(int i=0;i<=n;i++)f[i]=i,ans[i]=0;return ;}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <sstream>
using namespace std;
typedef long long ll;
const int N = 5e5 + 4;
const int X = 1e5;
int f[N], ans[N], a[1000], n, m;
bool dis[1000];
void ini(int n);
// ans[i] 到根节点的异或值;
// a[i] 输入序列;
int find(int u)
{
if(u == f[u])return u;
int t = f[u];
f[u] = find(f[u]);
ans[u] ^= ans[t];
return f[u];
}
bool unit(int x,int y,int z)
{
int a = find(x), b = find(y);
if(a == b) return ((ans[x]^ans[y]) != z);
if(a == n) swap(a,b);
f[a] = b;
ans[a] = ans[x]^ans[y]^z;
return 0;
}
int Q(int len)
{
int an = 0;
for(int i = 1;i < len;i ++)dis[i]=0;
for(int i = 1;i < len;i ++)
{
if(dis[i]) continue;
int t = find(a[i]), cnt = 0;
for(int j = i;j < len;j ++)
if(find(a[j]) == t)
{
dis[j] = 1; cnt++;
an ^= ans[a[j]];
}
if(cnt%2 == 1&&t != n)
return -1;
}
return an;
}
int main()
{
int TESTnum = 1;
while(~scanf("%d%d", &n, &m))
{
if(!n && !m) break;
printf("Case %d:\n",TESTnum++);
char op[20];
int Inum = 0, flag =0 , len;
ini(n);
while(m --)
{
scanf("%s",op);
int an = 0;
if(op[0]=='I')
{
Inum ++;
int u, v, w, space = 0;
getchar(); gets(op);
for(int i = 0;i < strlen(op);i ++)
space += (op[i]==' ');
if(space == 1) sscanf(op,"%d%d", &u, &w), v = n;
else sscanf(op,"%d%d%d", &u, &v, &w);
if(flag) continue;
if(unit(u, v, w))
printf("The first %d facts are conflicting.\n",Inum), flag = 1;
}
else
{
scanf("%d",&len);
len ++;
for(int i=1;i<len;i++)scanf("%d",a+i);
if(flag) continue;
int an = Q(len);
if(an == -1)puts("I don't know.");
else printf("%d\n", an);
}
}
puts("");
}
return 0;
}
void ini(int n){for(int i = 0;i <= n;i ++) f[i]=i, ans[i]=0; return ;}