题解 梦符

传送门

貌似强化成给一堆矩形更好做一点
考虑让每个有交矩形被统计恰好一次
用各个端点来回差分一下就行
使用主席树以达到 \(O(n\log n)\)

点击查看代码
// ubsan: undefined
// accoders
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#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 ll read() {
	ll 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, typ;

// namespace force{
// 	int a[N], l[N], r[N];
// 	void solve() {
// 		ll ans=0;
// 		for (int i=1; i<=n; ++i) a[i]=read(), l[i]=read(), r[i]=read();
// 		for (int i=1,L,R,u,v; i<=m; ++i) {
// 			L=read()^(ans*typ); R=read()^(ans*typ); u=read()^(ans*typ); v=read()^(ans*typ); ans=0;
// 			for (int j=1; j<=n; ++j)
// 				if ( (L<=a[j]&&a[j]<=R) && ((l[j]<=u&&u<=r[j])||(l[j]<=v&&v<=r[j])||(u<=l[j]&&l[j]<=v)||(u<=r[j]&&r[j]<=v)) )
// 					ans+=a[j];
// 			printf("%lld\n", ans);
// 		}
// 	}
// }

// namespace task1{
// 	int a[N], l[N], r[N];
// 	void solve() {
// 		ll ans=0;
// 		for (int i=1; i<=n; ++i) a[i]=read(), l[i]=read(), r[i]=read();
// 		for (int i=1,L,R,u,v; i<=m; ++i) {
// 			L=read()^(ans*typ); R=read()^(ans*typ); u=read()^(ans*typ); v=read()^(ans*typ); ans=0;
// 			for (int j=1; j<=n; ++j) if (a[j]<=R&&l[j]<=v) ans+=a[j];
// 			for (int j=1; j<=n; ++j) if (a[j]<L&&l[j]<=v) ans-=a[j];
// 			for (int j=1; j<=n; ++j) if (a[j]<=R&&r[j]<u) ans-=a[j];
// 			for (int j=1; j<=n; ++j) if (a[j]<L&&r[j]<u) ans+=a[j];
// 			printf("%lld\n", ans);
// 		}
// 	}
// }

namespace task2{
	#undef unix
	int a[N], l[N], r[N];
	vector<pair<int, int>> sta[N];
	int unix[N], uniy[N], xsiz, ysiz;
	#define ls(p) lson[p]
	#define rs(p) rson[p]
	#define pushup(p) suml[p]=suml[ls(p)]+suml[rs(p)], sumr[p]=sumr[ls(p)]+sumr[rs(p)]
	ll suml[N*40], sumr[N*40];
	int rot[N], lson[N*40], rson[N*40], tot, now;
	void updl(int& p1, int p2, int tl, int tr, int pos, int val) {
		p1=++tot;
		if (tl==tr) {suml[p1]=suml[p2]+val; sumr[p1]=sumr[p2]; return ;}
		int mid=(tl+tr)>>1;
		if (pos<=mid) updl(ls(p1), ls(p2), tl, mid, pos, val), rs(p1)=rs(p2);
		else updl(rs(p1), rs(p2), mid+1, tr, pos, val), ls(p1)=ls(p2);
		pushup(p1);
	}
	void updr(int& p1, int p2, int tl, int tr, int pos, int val) {
		p1=++tot;
		if (tl==tr) {sumr[p1]=sumr[p2]+val; suml[p1]=suml[p2]; return ;}
		int mid=(tl+tr)>>1;
		if (pos<=mid) updr(ls(p1), ls(p2), tl, mid, pos, val), rs(p1)=rs(p2);
		else updr(rs(p1), rs(p2), mid+1, tr, pos, val), ls(p1)=ls(p2);
		pushup(p1);
	}
	ll queryl(int p, int tl, int tr, int ql, int qr) {
		if (!p) return 0;
		if (ql<=tl&&qr>=tr) return suml[p];
		int mid=(tl+tr)>>1; ll ans=0;
		if (ql<=mid) ans+=queryl(ls(p), tl, mid, ql, qr);
		if (qr>mid) ans+=queryl(rs(p), mid+1, tr, ql, qr);
		return ans;
	}
	ll queryr(int p, int tl, int tr, int ql, int qr) {
		if (!p) return 0;
		if (ql<=tl&&qr>=tr) return sumr[p];
		int mid=(tl+tr)>>1; ll ans=0;
		if (ql<=mid) ans+=queryr(ls(p), tl, mid, ql, qr);
		if (qr>mid) ans+=queryr(rs(p), mid+1, tr, ql, qr);
		return ans;
	}
	void addl(int i, int tl, int tr, int pos, int val) {updl(rot[i], now, tl, tr, pos, val); now=rot[i];}
	void addr(int i, int tl, int tr, int pos, int val) {updr(rot[i], now, tl, tr, pos, val); now=rot[i];}
	ll queryl(int pos, int l, int r) {return queryl(rot[pos], 1, ysiz, l, r);}
	ll queryr(int pos, int l, int r) {return queryr(rot[pos], 1, ysiz, l, r);}
	void solve() {
		// cout<<double(sizeof(a)*8+sizeof(suml)*2+sizeof(lson)*2)/1000/1000<<endl; exit(0);
		for (int i=1; i<=n; ++i) {
			unix[++xsiz]=a[i]=read();
			uniy[++ysiz]=l[i]=read();
			uniy[++ysiz]=r[i]=read();
		}
		sort(unix+1, unix+xsiz+1);
		sort(uniy+1, uniy+ysiz+1);
		xsiz=unique(unix+1, unix+xsiz+1)-unix-1;
		ysiz=unique(uniy+1, uniy+ysiz+1)-uniy-1;
		for (int i=1; i<=n; ++i) {
			a[i]=lower_bound(unix+1, unix+xsiz+1, a[i])-unix;
			l[i]=lower_bound(uniy+1, uniy+ysiz+1, l[i])-uniy;
			r[i]=lower_bound(uniy+1, uniy+ysiz+1, r[i])-uniy;
			sta[a[i]].pb({l[i], r[i]});
		}
		for (int i=1; i<=xsiz; ++i) {
			for (auto& it:sta[i]) {
				addl(i, 1, ysiz, it.fir, unix[i]);
				addr(i, 1, ysiz, it.sec, unix[i]);
			}
		}
		ll L, R, u, v, ans=0;
		for (int i=1; i<=m; ++i) {
			L=read()^(ans*typ); R=read()^(ans*typ); u=read()^(ans*typ); v=read()^(ans*typ); ans=0;
			ans+=queryl(upper_bound(unix+1, unix+xsiz+1, R)-unix-1, 1, upper_bound(uniy+1, uniy+ysiz+1, v)-uniy-1);
			ans-=queryl(lower_bound(unix+1, unix+xsiz+1, L)-unix-1, 1, upper_bound(uniy+1, uniy+ysiz+1, v)-uniy-1);
			ans-=queryr(upper_bound(unix+1, unix+xsiz+1, R)-unix-1, 1, lower_bound(uniy+1, uniy+ysiz+1, u)-uniy-1);
			ans+=queryr(lower_bound(unix+1, unix+xsiz+1, L)-unix-1, 1, lower_bound(uniy+1, uniy+ysiz+1, u)-uniy-1);
			printf("%lld\n", ans);
		}
	}
}

signed main()
{
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);

	n=read(); m=read(); typ=read();
	// force::solve();
	// task1::solve();
	task2::solve();

	return 0;
}
posted @ 2022-07-26 16:40  Administrator-09  阅读(1)  评论(0编辑  收藏  举报