洛谷 P4148 簡單題 解題報告
阿新 • • 發佈:2019-02-04
bee lin mat 1.0 oot 大小 efi else if 單點
P4148 簡單題
題意
維護單點加與矩形求和,強制在線
說明
\(n\le 500000,m\le 200000\),\(4000ms / 20MB\)
kd-tree
復雜度我不懂
是一顆平衡樹,每一層以某一維的大小決定權值,像替罪羊那樣重構
Code:
#include <cstdio> #include <cctype> #include <algorithm> #define ls ch[now][0] #define rs ch[now][1] using std::min; using std::max; const int N=2e5+10; const int K=2; const double alpha=0.85; inline int read() { int x=0,f=1;char c=getchar(); while(!isdigit(c)) f=c=='-'?0:1,c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f?x:-x; } int ch[N][2],L[N][K],R[N][K],sum[N],siz[N],val[N],pos[N][2],tot; int num[N],cnt,ql[2],qr[2],nk,root; void updata(int now) { sum[now]=sum[ls]+sum[rs]+val[now]; siz[now]=siz[ls]+siz[rs]+1; for(int i=0;i<K;i++) { L[now][i]=R[now][i]=pos[now][i]; if(ls) L[now][i]=min(L[now][i],L[ls][i]),R[now][i]=max(R[now][i],R[ls][i]); if(rs) L[now][i]=min(L[now][i],L[rs][i]),R[now][i]=max(R[now][i],R[rs][i]); } } bool cmp(int a,int b){return pos[a][nk]<pos[b][nk];} void build(int &now,int l,int r,int k) { if(l>r){now=0;return;} int mid=l+r>>1;nk=k; std::nth_element(num+l,num+mid,num+r+1,cmp); now=num[mid]; build(ls,l,mid-1,k^1),build(rs,mid+1,r,k^1); updata(now); } void era(int now) { if(!now) return; era(ls),num[++cnt]=now,era(rs); } int New(int x,int y,int A) { siz[++tot]=1,sum[tot]=val[tot]=A; L[tot][0]=R[tot][0]=pos[tot][0]=x,L[tot][1]=R[tot][1]=pos[tot][1]=y; return tot; } void rebuild(int &now,int ins) { cnt=0,era(now),num[++cnt]=ins; build(now,1,cnt,0); } void Insert(int &now,int ins,int k) { if(!now) {now=ins;return;} if(pos[ins][k]<pos[now][k]) { if((siz[ls]+1)*1.0>siz[now]*alpha) rebuild(now,ins); else Insert(ls,ins,k^1); } else { if((siz[rs]+1)*1.0>siz[now]*alpha) rebuild(now,ins); else Insert(rs,ins,k^1); } updata(now); } bool ckin(int now) { return ql[0]<=L[now][0]&&qr[0]>=R[now][0]&&ql[1]<=L[now][1]&&qr[1]>=R[now][1]; } bool ckout(int now) { return qr[0]<L[now][0]||ql[0]>R[now][0]||qr[1]<L[now][1]||ql[1]>R[now][1]; } bool ckp(int now) { return ql[0]<=pos[now][0]&&pos[now][0]<=qr[0]&&ql[1]<=pos[now][1]&&pos[now][1]<=qr[1]; } int query(int now) { if(!now) return 0; if(ckin(now)) return sum[now]; if(ckout(now)) return 0; return (ckp(now)?val[now]:0)+query(ls)+query(rs); } #define beecute 233 int main() { int n=read(),op,x,y,A,las=0; while(beecute) { op=read(); if(op==1) x=read()^las,y=read()^las,A=read()^las,Insert(root,New(x,y,A),0); else if(op==2) ql[0]=read()^las,ql[1]=read()^las,qr[0]=read()^las,qr[1]=read()^las,printf("%d\n",las=query(root)); else break; } return 0; }
2019.2.4
洛谷 P4148 簡單題 解題報告