备忘录 : 树形结构…………
1.李超树
struct LCT{
int N=1000000;
struct Point{
int l;
int r;
int lid;
int rid;
int mid(){
return (l+r)>>1;
}
int v;
};
Point p[4919810];
#define lid (p[id].lid)
#define rid (p[id].rid)
int num;
int root[1919810];
int creat(int l,int r){
num++;
p[num].l=l;
p[num].r=r;
return num;
}
void build(int id){
// cout<<id<<endl;
root[id]=creat(1,N);
}
struct Segment{
int l;
int r;
double k;
double a;
double n(int x){
return a+k*(x-l);
}
};
Segment s[4919810];
int cnt=0;
int cp(int x,int y,int z){
if(y==0){
return x;
}
if(x==0){
return y;
}
double xn=s[x].n(z);
double yn=s[y].n(z);
if(yn-xn>=0.000000001){
return x;
}
else if(xn-yn>=0.000000001){
return y;
}else{
return min(x,y);
}
}
void insert(int x1,double y1,int x2,double y2){
if(x1>x2){
swap(x1,x2);
swap(y1,y2);
}
int l=x1;
int r=x2;
double a=y1;
double len=r-l;
double k;
if(len==0){
k=0;
a=y2;
} else{
k=(y2-y1)/len;
}
cnt++;
s[cnt].l=l;
s[cnt].r=r;
s[cnt].a=a;
s[cnt].k=k;
// cout<<l<<" "<<r<<" "<<a<<" "<<k<<endl;
gx(cnt,1);
}
void qry(double k,double b,int x){
cnt++;
s[cnt].l=0;
s[cnt].r=1000000;
s[cnt].a=b;
s[cnt].k=k;
// cout<<l<<" "<<r<<" "<<a<<" "<<k<<endl;
gx(cnt,root[x]);
}
void gx(int v,int id){
if(p[id].l==0){
return ;
}
// cout<<v<<" "<<id<<" "<<p[id].v<<" "<<s[v].l<<" "<<s[v].r<< " " <<p[id].l<<" "<<p[id].r<<endl;
if(s[v].l<=p[id].l&&s[v].r>=p[id].r){
// cout<<"?\n";
if(cp(v,p[id].v,p[id].mid())!=p[id].v){
// cout<<"Yes"<<" "<<v<<" "<<p[id].v<<endl;
swap(v,p[id].v);
// cout<<"Yes"<<" "<<v<<" "<<p[id].v<<endl;
}
if(v==0){
// cout<<"HAHA\n";
return ;
}
if(cp(v,p[id].v,p[id].l)!=p[id].v){
if(lid<=0&&p[id].l!=p[id].r){
lid=creat(p[id].l,p[id].mid());
}
gx(v,lid);
return ;
}
if(cp(v,p[id].v,p[id].r)!=p[id].v){
if(rid<=0&&p[id].l!=p[id].r){
rid=creat(p[id].mid()+1,p[id].r);
}
gx(v,rid);
return ;
}
// cout<<"PIGGOD\n";
return ;
}
if(s[v].l>p[id].mid()){
if(rid<=0&&p[id].l!=p[id].r){
rid=creat(p[id].mid()+1,p[id].r);
}
gx(v,rid);
return ;
}
if(s[v].r<=p[id].mid()){
if(lid<=0&&p[id].l!=p[id].r){
lid=creat(p[id].l,p[id].mid());
}
gx(v,lid);
return ;
}
if(lid<=0&&p[id].l!=p[id].r){
lid=creat(p[id].l,p[id].mid());
}
if(rid<=0&&p[id].l!=p[id].r){
rid=creat(p[id].mid()+1,p[id].r);
}
gx(v,lid);
gx(v,rid);
return ;
}
int sol(int x,int id){
if(p[id].l==p[id].r){
return p[id].v;
}
if(x<=p[id].mid()){
if(lid<=0&&p[id].l!=p[id].r){
lid=creat(p[id].l,p[id].mid());
}
return cp(p[id].v,sol(x,lid),x);
}else{
if(rid<=0&&p[id].l!=p[id].r){
rid=creat(p[id].mid()+1,p[id].r);
}
return cp(p[id].v,sol(x,rid),x);
}
}
} ;
2.KDtree
bool cmp0(int x,int y);
bool cmp1(int x,int y);
struct KDT{
struct Point{
int lid;
int rid;
int x;
int y;
int d;
int v;
int siz;
int num;
int x1=19198100,y1=19198100,x2=-19198100,y2=-19198100;
};
Point p[200810];
int cnt=0;
#define lid (p[id].lid)
#define rid (p[id].rid)
int creat(int x,int y,int x1,int x2,int y1,int y2){
cnt++;
p[cnt].x=x;
p[cnt].y=y;
p[cnt].x1=x1;
p[cnt].x2=x2;
p[cnt].y1=y1;
p[cnt].y2=y2;
p[cnt].siz=1;
p[cnt].d=1;
p[cnt].num=0;
return cnt;
}
int wtf[1919810]; //WaiT For build
int fc=0;
void cg(int id){
if(id==0){
return;
}
fc++;
wtf[fc]=id;
cg(lid);
cg(rid);
}
int build(int l,int r,int kill){
if(l>r){
return 0;
}
if(l==r){
int id= wtf[l];
p[id].d=kill;
p[id].siz=1;
lid=0;
rid=0;
p[id].x1=p[id].x;
p[id].x2=p[id].x;
p[id].y1=p[id].y;
p[id].y2=p[id].y;
p[id].v=p[id].num;
return wtf[l];
}
if(kill==0){
nth_element(wtf+l,wtf+(l+r)/2,wtf+r+1,cmp0);
}else{
nth_element(wtf+l,wtf+(l+r)/2,wtf+r+1,cmp1);
}
p[wtf[(l+r)/2]].d=kill;
int id=wtf[(l+r)/2];
lid=build(l,(l+r)/2-1,kill^1);
rid=build((l+r)/2+1,r,kill^1);
p[id].v=p[lid].v+p[rid].v+p[id].num;
p[id].siz=p[lid].siz+p[rid].siz+1;
p[id].x1=min(p[id].x,min(p[lid].x1,p[rid].x1));
p[id].y1=min(p[id].y,min(p[lid].y1,p[rid].y1));
p[id].x2=max(p[id].x,max(p[lid].x2,p[rid].x2));
p[id].y2=max(p[id].y,max(p[lid].y2,p[rid].y2));
return id;
}
int chec(int id){
if(id<=0){
return 0;
}
// cout<<p[id].siz*0.75<<endl;
p[id].siz=p[lid].siz+p[rid].siz+1;
if(max(p[lid].siz,p[rid].siz)>p[id].siz*0.75){
// cout<<"FUCKCCF";
cg(id);
int RE=build(1,fc,p[id].d);
fc=0;
return RE;
} else{
return id;
}
}
void insert(int x,int y,int v,int id){
// cout<<id<<endl;
if(p[id].siz==0){
creat(x,y,x,x,y,y);
}
// p[id].v+=v;
if(p[id].x==x&&p[id].y==y){
p[id].num+=v;
p[id].v=p[lid].v+p[rid].v+p[id].num;
p[id].x1=min(p[id].x,min(p[lid].x1,p[rid].x1));
p[id].y1=min(p[id].y,min(p[lid].y1,p[rid].y1));
p[id].x2=max(p[id].x,max(p[lid].x2,p[rid].x2));
p[id].y2=max(p[id].y,max(p[lid].y2,p[rid].y2));
return ;
}
if((x<p[id].x&&p[id].d==1)||(y<p[id].y&&p[id].d==0)){
if(!lid){
if(p[id].d==0){
lid=creat(x,y,p[id].x1,p[id].x2,p[id].y1,p[id].y-1);
p[lid].d=p[id].d^1;
}else{
lid=creat(x,y,p[id].x1,p[id].x-1,p[id].y1,p[id].y2);
p[lid].d=p[id].d^1;
}
}
insert(x,y,v,lid);
}else{
if(!rid){
if(p[id].d==0){
rid=creat(x,y,p[id].x1,p[id].x2,p[id].y,p[id].y2);
p[rid].d=p[id].d^1;
}else{
rid=creat(x,y,p[id].x,p[id].x2,p[id].y1,p[id].y2);
p[rid].d=p[id].d^1;
}
}
insert(x,y,v,rid);
}
lid=chec(lid);
rid=chec(rid);
// p[id].v=p[lid].v+p[rid].v;
p[id].v=p[lid].v+p[rid].v+p[id].num;
p[id].siz=p[lid].siz+p[rid].siz+1;
p[id].x1=min(p[id].x,min(p[lid].x1,p[rid].x1));
p[id].y1=min(p[id].y,min(p[lid].y1,p[rid].y1));
p[id].x2=max(p[id].x,max(p[lid].x2,p[rid].x2));
p[id].y2=max(p[id].y,max(p[lid].y2,p[rid].y2));
// cout<<id<<" "<<p[id].x1<<" "<<p[id].y1<<" "<<p[id].x2<<" "<<p[id].y2<<" "<<p[id].x<<" "<<p[id].y<<endl;
}
int sol(int x1,int x2,int y1,int y2,int id){
int ans=0;
//
if(p[id].siz==0) {
return 0;
}
p[id].v=p[lid].v+p[rid].v+p[id].num;
p[id].siz=p[lid].siz+p[rid].siz+1;
if(p[id].x>=x1&&p[id].x<=x2&&p[id].y>=y1&&p[id].y<=y2){
// cout<<"!!";
ans+=p[id].num;
}
if(p[id].x1>=x1&&p[id].x2<=x2&&p[id].y1>=y1&&p[id].y2<=y2){
// cout<<"!!";
return p[id].v;
}
if(p[id].d==0){
if(y2<p[id].y){
return sol(x1,x2,y1,y2,lid)+ans;
}
if(y1>p[id].y){
return sol(x1,x2,y1,y2,rid)+ans;
}
return sol(x1,x2,y1,y2,lid)+sol(x1,x2,y1,y2,rid)+ans;
}else{
if(x2<p[id].x){
return sol(x1,x2,y1,y2,lid)+ans;
}
if(x1>p[id].x){
return sol(x1,x2,y1,y2,rid)+ans;
}
return sol(x1,x2,y1,y2,lid)+sol(x1,x2,y1,y2,rid)+ans;
}
}
};
KDT t;
bool cmp0(int x,int y){
return t.p[x].y<t.p[y].y;
}
bool cmp1(int x,int y){
return t.p[x].x<t.p[y].x;
}
3.笛卡尔树(只有插入 代码最短的一集)
struct DKT{
struct Point{
int lid;
int rid;
int v;
int siz;
};
Point p[10190810];
int cnt=0;
int creat(int x){
cnt++;
p[cnt].siz=1;
p[cnt].v=x;
return cnt;
}
int s[10190810];
int r;
void insert(int x){
while(r>=1&&p[s[r]].v>x){
r--;
}
int New=creat(x);
p[s[r]].rid=New;
p[New].lid=s[r+1];
r++;
s[r]=New;
s[r+1]=0;
}
};
DKT t;

浙公网安备 33010602011771号