题解 一掷千金
因为是在补题解所以不再证一遍了,link
那么问题变为扫描线维护区间 lowbit 异或和
- 关于区间 lowbit 异或和:
一个神奇的事情是如果对 \([0, 2^{31})\) 开线段树,那么每个区间都形如 \([a2^b, (a+1)2^b)\)
然后一个这样的区间的 lowbit 异或和抵消后是 \(\operatorname{lowbit}(l)\oplus \operatorname{lowbit}(mid+1)\)(除叶子外)
就可以快速计算了
那么复杂度 \(O(n\log n)\)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, m, k;
namespace force{
int id[10][10], rec[N], fa[N], tot;
inline int getfa(int x, int y) {return id[max(1, x-1)][max(1, y-1)];}
int flip(int s, int u, int v) {
while (1) {
s^=1<<u;
if (u==v) break;
u=fa[u];
}
return s;
}
int dfs(int s) {
if (~rec[s]) return rec[s];
vector<int> uni;
// if (!s) return rec[s]=0;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) if (s&(1<<id[i][j])) {
int t=id[i][j];
while (1) {
uni.pb(dfs(flip(s, id[i][j], t)));
if (t==id[1][1]) break;
t=fa[t];
}
}
}
sort(uni.begin(), uni.end());
uni.erase(unique(uni.begin(), uni.end()), uni.end());
for (int i=0; ; ++i) {
if (i==uni.size()) return rec[s]=i;
if (uni[i]!=i) return rec[s]=i;
}
assert(0);
return rec[s]=-1;
}
void solve() {
memset(rec, -1, sizeof(rec));
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) id[i][j]=tot++;
int s=0;
for (int i=1; i<=k; ++i) {
int xl=read(), yl=read(), xr=read(), yr=read();
for (int a=xl; a<=xr; ++a)
for (int b=yl; b<=yr; ++b)
s|=1<<id[a][b];
}
for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) fa[id[i][j]]=getfa(i, j);
cout<<dfs(s)<<endl;
}
}
namespace task{
int ans;
#define ls(p) lson[p]
#define rs(p) rson[p]
#define lowbit(i) ((i)&-(i))
vector<pair<int, int>> add[N], del[N];
int lson[N*100], rson[N*100], val[N*100], cover[N*100], cnt[N*100], tot, rot;
inline int qsum(int l, int r) {int ans=0; for (int i=l; i<=r; ++i) ans^=lowbit(i); return ans;}
void upd(int& p, int tl, int tr, int ql, int qr, int dat) {
if (!p) p=++tot;
int mid=(tl+tr)>>1;
if (ql<=tl&&qr>=tr) {
if (cover[p]+=dat) val[p]=(tl==tr)?lowbit(tl):(lowbit(tl)^lowbit(mid+1)), cnt[p]=tr-tl+1;
else val[p]=val[ls(p)]^val[rs(p)], cnt[p]=cnt[ls(p)]+cnt[rs(p)];
return ;
}
if (ql<=mid) upd(ls(p), tl, mid, ql, qr, dat);
if (qr>mid) upd(rs(p), mid+1, tr, ql, qr, dat);
if (cover[p]) val[p]=(tl==tr)?lowbit(tl):(lowbit(tl)^lowbit(mid+1)), cnt[p]=tr-tl+1;
else val[p]=val[ls(p)]^val[rs(p)], cnt[p]=cnt[ls(p)]+cnt[rs(p)];
}
int qval(int p, int tl, int tr, int ql, int qr, bool covered) {
int mid=(tl+tr)>>1;
if (ql<=tl&&qr>=tr) return covered?((tl==tr)?lowbit(tl):(lowbit(tl)^lowbit(mid+1))):val[p];
if (ql<=mid&&qr>mid) return qval(ls(p), tl, mid, ql, qr, covered|bool(cover[p]))^qval(rs(p), mid+1, tr, ql, qr, covered|bool(cover[p]));
else if (ql<=mid) return qval(ls(p), tl, mid, ql, qr, covered|bool(cover[p]));
else return qval(rs(p), mid+1, tr, ql, qr, covered|bool(cover[p]));
}
int qcnt(int p, int tl, int tr, int ql, int qr, bool covered) {
if (ql<=tl&&qr>=tr) return covered?tr-tl+1:cnt[p];
int mid=(tl+tr)>>1, ans=0;
if (ql<=mid) ans+=qcnt(ls(p), tl, mid, ql, qr, covered|bool(cover[p]));
if (qr>mid) ans+=qcnt(rs(p), mid+1, tr, ql, qr, covered|bool(cover[p]));
return ans;
}
// void upd(int& p, int tl, int tr, int ql, int qr, int dat) {for (int i=ql; i<=qr; ++i) cover[i]+=dat;}
// int qval(int p, int tl, int tr, int ql, int qr) {int ans=0; for (int i=ql; i<=qr; ++i) if (cover[i]) ans^=lowbit(i); return ans;}
// int qcnt(int p, int tl, int tr, int ql, int qr) {int ans=0; for (int i=ql; i<=qr; ++i) if (cover[i]) ++ans; return ans;}
void solve() {
for (int i=1; i<=k; ++i) {
int xl=read(), yl=read(), xr=read(), yr=read();
add[xl].pb({yl, yr}); del[xr].pb({yl, yr});
}
for (int i=1; i<=n; ++i) {
for (auto it:add[i]) upd(rot, 0, (1<<30)-1, it.fir, it.sec, 1);
ans^=qval(rot, 0, (1<<30)-1, i, (1<<30)-1, 0);
if (qcnt(rot, 0, (1<<30)-1, 0, i-1, 0)&1) ans^=lowbit(i);
for (auto it:del[i]) upd(rot, 0, (1<<30)-1, it.fir, it.sec, -1);
}
printf("%d\n", ans);
}
}
signed main()
{
k=read(); n=read(); m=read();
// force::solve();
task::solve();
return 0;
}