bzoj4066: 简单题 K-Dtree

匿名 (未验证) 提交于 2019-12-02 23:49:02

bzoj

˼·

强制在线。k-dtree。
卡常啊。空间开1e6就T了。

#include <bits/stdc++.h> #define my_min(a,b) (a<b?a:a=b) #define my_max(a,b) (a>b?a:a=b) using namespace std; const double alpha=0.75; const int N=2e5+7; int read() {     int x=0,f=1;     char s=getchar();     for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1;     for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0';     return x*f; } int WD,lastans; struct point {     int x[2],v;     bool operator < (const point &b) const {         return x[WD]<b.x[WD];     } } p[N]; struct node {     int ls,rs,mi[2],ma[2],sum,siz;     point a; } e[N]; int rub[N],top,cnt; int newnode() {     if(top) return rub[top--];     return ++cnt; } void update(int x,int y) {     my_min(e[x].mi[0],e[y].mi[0]);     my_min(e[x].mi[1],e[y].mi[1]);     my_max(e[x].ma[0],e[y].ma[0]);     my_max(e[x].ma[1],e[y].ma[1]); } void up(int u) {     int ls=e[u].ls,rs=e[u].rs;     e[u].mi[0]=e[u].ma[0]=e[u].a.x[0];     e[u].mi[1]=e[u].ma[1]=e[u].a.x[1];     e[u].sum=e[ls].sum+e[rs].sum+e[u].a.v;     e[u].siz=e[ls].siz+e[rs].siz+1;     if(ls) update(u,ls);     if(rs) update(u,rs); } int build(int l,int r,int wd) {     if(l>r) return 0;     int mid=(l+r)>>1;     WD=wd;     nth_element(p+l,p+mid,p+r+1);     int u=newnode();     e[u].a=p[mid];     e[u].ls=build(l,mid-1,wd^1);     e[u].rs=build(mid+1,r,wd^1);     up(u);     return u; } void pia(int u,int num) {     if(e[u].ls) pia(e[u].ls,num);     p[num+e[e[u].ls].siz+1]=e[u].a;     rub[++top]=u;     if(e[u].rs) pia(e[u].rs,num+e[e[u].ls].siz+1); } int check(int &u,int wd) {     if(alpha*e[u].siz<e[e[u].ls].siz||alpha*e[u].siz<e[e[u].rs].siz)         pia(u,0),u=build(1,e[u].siz,wd); } void insert(point a,int &rt,int wd) {     if(!rt) {         rt=newnode();         e[rt].a=a;         e[rt].ls=e[rt].rs=0;         up(rt);         return;     }     if(e[rt].a.x[wd]<a.x[wd]) insert(a,e[rt].rs,wd^1);     else insert(a,e[rt].ls,wd^1);     up(rt);     check(rt,wd); } int pd(node a,int x,int y,int X,int Y) {     if(x<=a.mi[0]&&a.ma[0]<=X&&y<=a.mi[1]&&a.ma[1]<=Y) return 1;     if(a.ma[0]<x||X<a.mi[0]) return 0;     if(a.ma[1]<y||Y<a.mi[1]) return 0;     return 2; } void query(int rt,int x,int y,int X,int Y) {     if(x<=e[rt].a.x[0]&&e[rt].a.x[0]<=X             &&y<=e[rt].a.x[1]&&e[rt].a.x[1]<=Y) lastans+=e[rt].a.v;     int ls=e[rt].ls,rs=e[rt].rs;     if(ls) {         int PD=pd(e[ls],x,y,X,Y);         if(PD==1) lastans+=e[ls].sum;         if(PD==2) query(ls,x,y,X,Y);     }     if(rs) {         int PD=pd(e[rs],x,y,X,Y);         if(PD==1) lastans+=e[rs].sum;         if(PD==2) query(rs,x,y,X,Y);     } } int main() {     int rt=0,n=read();     while(233) {         int opt=read();         if(opt==1) {             point a;             a.x[0]=read()^lastans,a.x[1]=read()^lastans,a.v=read()^lastans;             insert(a,rt,0);         } else if(opt==2) {             int x=read()^lastans,y=read()^lastans,X=read()^lastans,Y=read()^lastans;             lastans=0;             query(rt,x,y,X,Y);             printf("%d\n",lastans);         } else break;     }     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!