题解 一掷千金

传送门

因为是在补题解所以不再证一遍了,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;
}
posted @ 2022-05-25 08:05  Administrator-09  阅读(1)  评论(0编辑  收藏  举报