题解 梦符
貌似强化成给一堆矩形更好做一点
考虑让每个有交矩形被统计恰好一次
用各个端点来回差分一下就行
使用主席树以达到 \(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;
}