【NOIP2017提高A組模擬9.17】信仰是為了虛無之人
阿新 • • 發佈:2020-11-25
【NOIP2017提高A組模擬9.17】信仰是為了虛無之人
Description
Input
Output
Sample Input
3 3 0
1 1 7
1 1 6
1 3 2
Sample Output
1
0
1
7
0
5
Data Constraint
題解
判斷真假考慮並查集,設\(g[i]\)表示從當前這棵樹的根到\(i\)的字首異或值,那麼對於當前這個區間,\(l-1\)和\(r\)討論
設\(f1\)是\(l-1\)的根,\(f2\)是\(r\)的根
- 如果\(f1=f2\),說明是同一棵樹,那麼只有\(k=g[r]\ xor\ g[l-1]\)成立的時候才是真
- 如果\(f1!=f2\)
在並查集\(find\)的時候同時更新\(g[i]\)
設\(s[i]\)表示\(1\)~\(i-1\)的最小異或值
求最小值時,如果當前這個點是祖先,說明這個點的取值沒有限制,自然取0最優:\(s[i]=s[i-1]\)。如果不是祖先,那麼這個點要填的就是\(g[i]\),\(s[i]=s[find(i)]^\ xor\ g[i]\)
輸出\(s[i]\ xor\ s[i-1]\)
Code
#include<cstdio> #include<algorithm> using namespace std; int n,m,pd,l,r,k,last,f1,f2,x,f[200001],g[200001],sum[200001]; int read() { int res=0,fh=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') fh=-1,ch=getchar(); while (ch>='0'&&ch<='9') res=(res<<1)+(res<<3)+(ch-'0'),ch=getchar(); return res*fh; } int find(int x) { if (f[x]==x) return x; int xx=find(f[x]); g[x]^=g[f[x]]; return f[x]=xx; } int main() { freopen("sanae.in","r",stdin); freopen("sanae.out","w",stdout); n=read();m=read();pd=read(); for (int i=1;i<=n;++i) f[i]=i; while (m--) { l=read();r=read();k=read(); if (pd) l^=last,r^=last,k^=last; f1=find(l-1);f2=find(r); if (f1==f2) { if ((g[l-1]^g[r])==k) last=1; else last=0; printf("%d\n",last); } else { if (f1>f2) swap(f1,f2); f[f2]=f1; g[f2]^=g[l-1]^g[r]^k; last=1; printf("%d\n",last); } } for (int i=1;i<=n;++i) { x=find(i); if (i==x) sum[i]=sum[i-1]; else sum[i]=sum[x]^g[i]; printf("%d\n",sum[i]^sum[i-1]); } fclose(stdin); fclose(stdout); return 0; }