首页 > 其他 > 详细

崂山白花蛇草水 权值线段树套KDtree

时间:2019-06-01 14:46:54      阅读:120      评论:0      收藏:0      [点我收藏+]

Code:

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) //,freopen(s".out","w",stdout) 
struct Data
{
	int ch[2],w,minv[2],maxv[2],p[2],siz,sum;  
}node[20000000], arr[20000000]; 
namespace KDtree
{
	#define maxn 20000000
	#define Min(a,b) (a = a>b?b:a) 
	#define Max(a,b) (a = b>a?b:a) 
	int d,c_arr;    
	std::queue<int>Q; 
	void Init()
	{
		for(int i=1;i<maxn;++i) Q.push(i);                
	} 
    int newnode(){ int q = Q.front(); Q.pop(); return q; }
	bool cmp(Data i,Data j)
	{      
		return i.p[d]==j.p[d]?i.p[d^1]<j.p[d^1]:i.p[d]<j.p[d]; 
	}
	bool isout(int k,int x1,int y1,int x2,int y2)
	{
		if(node[k].maxv[0]<x1||node[k].minv[0]>x2||node[k].maxv[1]<y1||node[k].minv[1]>y2) return 1; 
		return 0; 
	}
	bool isin(int k,int x1,int y1,int x2,int y2)
	{
		if(node[k].maxv[0]<=x2 && node[k].minv[0]>=x1&&node[k].maxv[1]<=y2&&node[k].minv[1]>=y1) return 1; 
		return 0; 
	}
	void pushup(int x,Data p)
	{
		node[x].sum+=p.sum;
		node[x].siz+=p.siz; 
		Min(node[x].minv[0],p.minv[0]); 
		Min(node[x].minv[1],p.minv[1]); 
		Max(node[x].maxv[0],p.maxv[0]); 
		Max(node[x].maxv[1],p.maxv[1]); 
	}
	int query(int x,int x1,int y1,int x2,int y2)
	{
		if(!x||isout(x,x1,y1,x2,y2)) return 0; 
		if(isin(x,x1,y1,x2,y2))  
        {
            return node[x].sum; 
        }
		int ans=0; 
		if(node[x].p[0]>=x1&&node[x].p[0]<=x2&&node[x].p[1]>=y1&&node[x].p[1]<=y2) ans=1; 
		ans += query(node[x].ch[0],x1,y1,x2,y2)+query(node[x].ch[1],x1,y1,x2,y2); 
		return ans; 
	} 
	void dfs(int &o)
	{
		if(!o) return; 
		dfs(node[o].ch[0]);
		arr[++c_arr] = node[o];
		arr[c_arr].sum=arr[c_arr].w=1; 
		arr[c_arr].maxv[0]=arr[c_arr].minv[0]=arr[c_arr].p[0]; 
		arr[c_arr].maxv[1]=arr[c_arr].minv[1]=arr[c_arr].p[1]; 
		arr[c_arr].siz=1;      
		Q.push(o);
		dfs(node[o].ch[1]); 
		o=0; 
	}   
	void rebuild(int &x,int l,int r,int o)
	{
		int mid=(l+r)>>1; 
		d=o,std::nth_element(arr+l,arr+mid,arr+1+r,cmp); 
		x=newnode(); 
		node[x]=arr[mid]; 
		node[x].minv[0]=node[x].maxv[0]=node[x].p[0]; 
		node[x].minv[1]=node[x].maxv[1]=node[x].p[1]; 
		node[x].sum=node[x].w=1;  
		node[x].ch[0]=node[x].ch[1]=0;
		node[x].siz=1; 
		if(l<mid) rebuild(node[x].ch[0],l,mid-1,o^1), pushup(x, node[node[x].ch[0]]); 
		if(r>mid) rebuild(node[x].ch[1],mid+1,r,o^1), pushup(x, node[node[x].ch[1]]); 
	} 
	void Reconstruct(int &u)
	{
		c_arr=0; 
		dfs(u); 
		rebuild(u,1,c_arr,d=0);       
	} 
	bool check(int son,int x)
	{ 
		if(son*10>x*9) return true; 
		return false; 
	}
	void insert(int &x,Data a,int de,int tag)
	{
		if(!x)
		{
			x=newnode(); 
			node[x].p[0]=node[x].maxv[0]=node[x].minv[0]=a.p[0]; 
			node[x].p[1]=node[x].maxv[1]=node[x].minv[1]=a.p[1]; 
			node[x].sum=node[x].w=1;
			node[x].siz=1,node[x].ch[0]=node[x].ch[1]=0; 
			return; 
		}
		d = de;
		int is=0;          
		if(cmp(a,node[x]) == 1)          
		{                    
			is = check(node[node[x].ch[0]].siz+1,node[x].siz+1);
			insert(node[x].ch[0],a,de^1,is||tag);
			pushup(x,a); 
		}
		//a is bigger (rson) 
		else 
		{
			is = check(node[node[x].ch[1]].siz+1,node[x].siz+1);
			insert(node[x].ch[1],a,de^1,is||tag);
			pushup(x,a); 
		}      
	if(tag && is) Reconstruct(x);   
	}
};       
#define y1 opopopop 
int lson[2000000],rson[2000000],rt[2000000]; 
int x1,y1,x2,y2, tot=0,root=0;  
void modify(int &x,int l,int r,int k,Data i)
{   
	if(!x) x = ++tot;           
	KDtree::insert(rt[x],i,0,0);                  
	if(l==r) return;         
	int mid = (l+r)>>1; 
	if(k <= mid) modify(lson[x],l,mid,k,i); 
	else modify(rson[x],mid+1,r,k,i); 
}        
int query(int x,int l,int r,int kth)
{              
	if(l==r) return l; 
	int u = KDtree::query(rt[rson[x]],x1,y1,x2,y2);                     
	int mid = (l + r) >> 1;             
	if(u < kth) 
	    return query(lson[x],l,mid,kth-u);  
	else 
	    return query(rson[x],mid+1,r,kth);  
}
int Query(int kth)
{    
	return query(root,0,1000000000,kth);      
}
int n,q,lastans=0; 
int main()
{
 	// setIO("input"); 
	KDtree::Init();  
	scanf("%d%d",&n,&q);            
	for(int cc=1;cc<=q;++cc)   
	{
		int opt,a,b,c,d; 
		scanf("%d",&opt); 
		if(opt==1)
		{    
			scanf("%d%d%d",&a,&b,&c);     
            a^=lastans,b^=lastans,c^=lastans; 
			Data f; 
			f.p[0]=f.maxv[0]=f.minv[0]=a;
			f.p[1]=f.maxv[1]=f.minv[1]=b; 
			f.ch[0]=f.ch[1]=0; 
			f.siz=1;    
			f.sum=f.w=1;                 
			modify(root,0,1000000000,c,f);   
		}
		if(opt==2)
		{
			scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&a); 
		    x1^=lastans,y1^=lastans,x2^=lastans,y2^=lastans,a^=lastans;             
			lastans = Query(a); 
			if(lastans==0)   
			    printf("NAIVE!ORZzyz.\n");   
			else  
			    printf("%d\n",lastans); 
		}
	}
	return 0; 
}     

  

崂山白花蛇草水 权值线段树套KDtree

原文:https://www.cnblogs.com/guangheli/p/10959473.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!