题解:P6532 [COCI 2015/2016 #1] TOPOVI
P6532 [COCI 2015/2016 #1] TOPOVI
分析
如果一个点不可以被攻击,那么列异或和异或行异或和为 0。
即如果对于一行来看,如果这一行所有元素都异或上了 x,那么不可以被攻击到的点的个数就是异或和为 x 的列数。
那么如果加入修改,那么我们可以用 map 维护某一异或和对应的列数或行数,然后每次改变时更新。
那么就很好实现了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<int, ll> rxor, cxor, rcnt, ccnt;
map<pair<int, int>, int> mp;
int n, k, p;
ll ans = 0; // 可以被攻击到的点
void update(int x, int y, int w) {
int R, C;
R = rxor[x], C = cxor[y];
ans -= n - rcnt[C] + n - ccnt[R];
if (R ^ C) ans++;
rcnt[R]--;
ccnt[C]--;
rxor[x] ^= w;
cxor[y] ^= w;
R = rxor[x], C = cxor[y];
rcnt[rxor[x]]++;
ccnt[cxor[y]]++;
ans += n - rcnt[C] + n - ccnt[R];
if (R ^ C) ans--;
mp[{x, y}] ^= w;
}
int main() {
cin >> n >> k >> p;
rcnt[0] = ccnt[0] = n;
for (int i = 1;i <= k;i++) {
int x, y, w;
cin >> x >> y >> w;
update(x, y, w);
}
for (int i = 1;i <= p;i++) {
int r1, r2, c1, c2;
cin >> r1 >> c1 >> r2 >> c2;
int w = mp[{r1, c1}];
update(r1, c1, w);
update(r2, c2, w);
cout << ans << "\n";
}
return 0;
}

浙公网安备 33010602011771号