今天突然想写个树套树爽一爽(1810ms)
写的是树状数组套线段树(动态开节点)
#include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } const int maxn=200010; const int maxnode=20000010; int sum[maxnode],ls[maxnode],rs[maxnode],ToT; void update(int& y,int l,int r,int& pos,int& v) { if(!y) y=++ToT; sum[y]+=v;if(l==r) return; int mid=l+r>>1; if(pos<=mid) update(ls[y],l,mid,pos,v); else update(rs[y],mid+1,r,pos,v); } int ans; void query(int& y,int l,int r,int& ql,int& qr) { if(ql<=l&&r<=qr) {ans+=sum[y];return;} if(!y) return; int mid=l+r>>1; if(ql<=mid) query(ls[y],l,mid,ql,qr); if(qr>mid) query(rs[y],mid+1,r,ql,qr); } int n,root[maxn],lastans; void add(int x,int y,int v) { for(;x<=400000;x+=x&-x) update(root[x],1,400000,y,v); } int query(int x,int ql,int qr) { ans=0; for(;x;x-=x&-x) query(root[x],1,400000,ql,qr); return ans; } int tp[200010],x1[200010],x2[200010],y1[200010],y2[200010],v[200010]; int tmp[400010],tot; int main() { read();n=read();int m; for(int i=1;;i++) { tp[i]=read(); if(tp[i]==3) {m=i;break;} else if(tp[i]==1) x1[i]=read(),y1[i]=read(),v[i]=read(); else x1[i]=read(),y1[i]=read(),x2[i]=read(),y2[i]=read(),tmp[++tot]=x2[i]; tmp[++tot]=x1[i]; } sort(tmp+1,tmp+tot+1); for(int i=1;i<=m;i++) x1[i]=lower_bound(tmp+1,tmp+tot+1,x1[i])-tmp,x2[i]=lower_bound(tmp+1,tmp+tot+1,x2[i])-tmp; tot=0;for(int i=1;i<=m;i++) tmp[++tot]=y1[i],tmp[++tot]=y2[i];sort(tmp+1,tmp+tot+1); for(int i=1;i<=m;i++) y1[i]=lower_bound(tmp+1,tmp+tot+1,y1[i])-tmp,y2[i]=lower_bound(tmp+1,tmp+tot+1,y2[i])-tmp; for(int i=1;i<=m;i++) { if(tp[i]==3) break; else if(tp[i]==1) add(x1[i],y1[i],v[i]); else printf("%d\n",query(x2[i],y1[i],y2[i])-query(x1[i]-1,y1[i],y2[i])); } return 0; }