G
N
I
D
A
O
L

备忘录 : 树形结构…………

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;

posted @ 2025-08-25 16:47  MagicalGirl_MH  阅读(12)  评论(0)    收藏  举报