并查集。对于对元素赋值操作,更改为I p n v。令val[n]=0(任何数与0异或仍为原值)。
考虑fa[x] = fx, fa[y] = fy。
如果使得fa[fx] = fy, 那么val[fx] = TrueVal[fx] ^ TrueVal[fy] = (val[x] ^ TrueVal[x]) ^ (val[y] ^ TrueVal[y]) = (val[x] ^ val[y]) ^ (TrueVal[x] ^ TrueVal[y]) = val[x] ^ val[y] ^ z。
同时每次find时,也需要更新val(因为fa不同了)。
对于Query操作,有效的Query为cnt为偶数或者root为n。
输出样例有问题,每个case后有空行。
1 /* 3234 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxn = 2e4+5; 43 const int maxk = 20; 44 int fa[maxn], val[maxn]; 45 int P[maxk], K; 46 bool visit[maxk]; 47 int n; 48 49 int find(int x) { 50 if (fa[x] == x) 51 return x; 52 int tmp = fa[x]; 53 fa[x] = find(fa[x]); 54 val[x] ^= val[tmp]; 55 return fa[x]; 56 } 57 58 void init() { 59 rep(i, 0, n+1) { 60 val[i] = 0; 61 fa[i] = i; 62 } 63 } 64 65 bool merge(int u, int v, int x) { 66 int fu = find(u); 67 int fv = find(v); 68 69 if (fu == fv) { 70 return (val[u]^val[v]) == x; 71 } 72 73 if (fu == n) swap(fu, fv); 74 fa[fu] = fv; 75 val[fu] = val[u]^val[v]^x; 76 return true; 77 } 78 79 int Query() { 80 int f, c; 81 int ret = 0; 82 83 memset(visit, false, sizeof(visit)); 84 rep(i, 0, K) 85 find(P[i]); 86 rep(i, 0, K) { 87 if (visit[i]) 88 continue; 89 f = fa[P[i]]; 90 c = 0; 91 rep(j, i, K) { 92 if (!visit[j] && fa[P[j]]==f) { 93 ++c; 94 visit[j] = true; 95 ret ^= val[P[j]]; 96 } 97 } 98 if (f!=n && (c&1)) 99 return -1; 100 } 101 102 return ret; 103 } 104 105 int main() { 106 ios::sync_with_stdio(false); 107 #ifndef ONLINE_JUDGE 108 freopen("data.in", "r", stdin); 109 freopen("data.out", "w", stdout); 110 #endif 111 112 int q; 113 int isn; 114 int a[5], c; 115 int u, v, x; 116 int ans; 117 char cmd[3], line[105]; 118 bool flag; 119 int t = 0; 120 121 while (scanf("%d %d", &n, &q)!=EOF && (n||q)) { 122 printf("Case %d:\n", ++t); 123 init(); 124 flag = true; 125 isn = 0; 126 while (q--) { 127 scanf("%s%*c", cmd); 128 if (cmd[0] == ‘I‘) { 129 gets(line); 130 } else { 131 scanf("%d", &K); 132 rep(i, 0, K) 133 scanf("%d", &P[i]); 134 } 135 if (!flag) 136 continue; 137 138 if (cmd[0] == ‘I‘) { 139 int len = strlen(line); 140 141 ++isn; 142 c = 0; 143 a[c] = 0; 144 rep(i, 0, len) { 145 if (line[i] == ‘ ‘) { 146 ++c; 147 a[c] = 0; 148 } else { 149 a[c] = 10*a[c] + line[i]-‘0‘; 150 } 151 } 152 153 if (c == 1) { 154 u = a[0]; 155 v = n; 156 x = a[1]; 157 } else { 158 u = a[0]; 159 v = a[1]; 160 x = a[2]; 161 } 162 163 flag = merge(u, v, x); 164 165 if (!flag) { 166 printf("The first %d facts are conflicting.\n", isn); 167 } 168 } else { 169 ans = Query(); 170 if (ans == -1) { 171 puts("I don‘t know."); 172 } else { 173 printf("%d\n", ans); 174 } 175 } 176 } 177 178 putchar(‘\n‘); 179 } 180 181 #ifndef ONLINE_JUDGE 182 printf("time = %d.\n", (int)clock()); 183 #endif 184 185 return 0; 186 }
时间: 2024-10-13 07:36:08