题意:两道题差不多,都是给你一堆平面上的点,每个点有权值,然后m次询问求某一矩形区域内的点权和
题解:先离散化,然后将询问拆成左右两条线段,然后将点和这些线段一起按x坐标排序,在y轴上维护树状数组。然后询问的答案就是两条线段上点权和之差
BZOJ1935:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int s[1000010]; struct QUERY { int qx,ql,qr,org,k; }q[1000010]; struct tree { int px,py; }p[500010]; int n,m,nm; int ans[500010]; int rd() { int ret=0; char gc=getchar(); while(gc<'0'||gc>'9') gc=getchar(); while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret; } bool cmp1(tree a,tree b) { return a.px<b.px; } bool cmp2(QUERY a,QUERY b) { return a.qx<b.qx; } void updata(int x) { for(int i=x;i<=nm;i+=i&-i) s[i]++; } int query(int x) { int i,ret=0; for(i=x;i;i-=i&-i) ret+=s[i]; return ret; } int main() { n=rd(),m=rd(); int i,j; for(i=1;i<=n;i++) p[i].px=rd(),p[i].py=rd()+1; for(i=1;i<=m;i++) q[i*2-1].qx=rd()-1,q[i*2-1].ql=q[i*2].ql=rd(),q[i*2].qx=rd(),q[i*2-1].qr=q[i*2].qr=rd()+1, q[i*2-1].org=q[i*2].org=i,q[i*2-1].k=-1,q[i*2].k=1,nm=max(nm,q[i*2].qr); sort(p+1,p+n+1,cmp1); sort(q+1,q+2*m+1,cmp2); for(i=j=1;i<=2*m;i++) { for(;j<=n&&p[j].px<=q[i].qx;j++) updata(p[j].py); ans[q[i].org]+=q[i].k*(query(q[i].qr)-query(q[i].ql)); } for(i=1;i<=m;i++) printf("%d ",ans[i]); return 0; }
BZOJ4822
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; struct QUERY { int qx,ql,qr,org,k; }q[200010]; struct tree { int px,py; ll pow; }p[100010]; int n,m,nm; ll ans[100010],s[400010]; struct node { int num,org,k; }v[500010]; int rd() { int ret=0,f=1; char gc=getchar(); while(gc<'0'||gc>'9'){if(gc=='-')f=-f; gc=getchar();} while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar(); return ret*f; } bool cmp(node a,node b) { return a.num<b.num; } bool cmp1(tree a,tree b) { return a.px<b.px; } bool cmp2(QUERY a,QUERY b) { return a.qx<b.qx; } void updata(int x,ll val) { for(int i=x;i<=nm;i+=i&-i) s[i]+=val; } ll query(int x) { int i; ll ret=0; for(i=x;i;i-=i&-i) ret+=s[i]; return ret; } int main() { n=rd(),m=rd(); int i,j; for(i=1;i<=n;i++) p[i].px=rd(),v[i].num=rd(),p[i].pow=rd(),v[i].org=i,v[i].k=1; for(i=1;i<=m;i++) q[i*2-1].qx=rd()-1,v[i*2-1+n].num=rd()-1,q[i*2].qx=rd(),v[i*2+n].num=rd(), q[i*2-1].org=q[i*2].org=i,q[i*2-1].k=-1,q[i*2].k=1,v[i*2-1+n].org=v[i*2+n].org=i, v[i*2-1+n].k=2,v[i*2+n].k=3; sort(v+1,v+n+2*m+1,cmp); for(i=1;i<=n+2*m;i++) { if(v[i].num>v[i-1].num||i==1) nm++; if(v[i].k==1) p[v[i].org].py=nm; if(v[i].k==2) q[2*v[i].org-1].ql=q[2*v[i].org].ql=nm; if(v[i].k==3) q[2*v[i].org-1].qr=q[2*v[i].org].qr=nm; } sort(p+1,p+n+1,cmp1); sort(q+1,q+2*m+1,cmp2); for(i=j=1;i<=2*m;i++) { for(;j<=n&&p[j].px<=q[i].qx;j++) updata(p[j].py,p[j].pow); ans[q[i].org]+=(ll)q[i].k*(query(q[i].qr)-query(q[i].ql)); } for(i=1;i<=m;i++) printf("%lld ",ans[i]); return 0; }