zoukankan      html  css  js  c++  java
  • P4148 简单题 KDTree

    KDtree模板题

    不会的看这里

    本题离线的话就是裸的cdq分治

    强制在线那就按维分割,加入新点的话类似于建树过程,同时记录一下点的范围,以便询问的时候好剪枝

    为了防止出题人毒瘤(比如让你建的树成了一条链),你可以每过一段时间重构一下这棵树。

    代码虽长,但很好写

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int d,root;
    const int N=490001;
    struct data
    {
        int p[2],maxn[2],minn[2],c[2],w,sum;
    }a[N];
    bool cmp(data a,data b)
    {
        return a.p[d]==b.p[d]?a.p[d^1]<b.p[d^1]:a.p[d]<b.p[d];
    }
    void pushup(int k,int s)
    {
        a[k].maxn[0]=max(a[k].maxn[0],a[s].maxn[0]);
        a[k].minn[0]=min(a[k].minn[0],a[s].minn[0]);
        a[k].maxn[1]=max(a[k].maxn[1],a[s].maxn[1]);
        a[k].minn[1]=min(a[k].minn[1],a[s].minn[1]);
        a[k].sum+=a[s].sum;
    }
    int build(int l,int r,int now)
    {
    	int mid=(l+r)>>1;d=now;
    	nth_element(a+l,a+mid,a+1+r,cmp);
    	a[mid].maxn[0]=a[mid].minn[0]=a[mid].p[0];
    	a[mid].maxn[1]=a[mid].minn[1]=a[mid].p[1];
    	a[mid].sum=a[mid].w;
    	a[mid].c[0]=a[mid].c[1]=0;
    	if(l<mid)a[mid].c[0]=build(l,mid-1,now^1),pushup(mid,a[mid].c[0]);
        if(r>mid)a[mid].c[1]=build(mid+1,r,now^1),pushup(mid,a[mid].c[1]);
        return mid;
    }
    void Insert(int x)
    {
    	int *t=&root;d=0;
    	while(*t)pushup(*t,x),t=&a[*t].c[a[x].p[d]>a[*t].p[d]],d^=1;
    	*t=x;
    }
    int query(int k,int x1,int y1,int x2,int y2)
    {
        if(!k||a[k].maxn[0]<x1||x2<a[k].minn[0]||a[k].maxn[1]<y1||y2<a[k].minn[1])return 0;
        if(x1<=a[k].minn[0]&&a[k].maxn[0]<=x2&&y1<=a[k].minn[1]&&a[k].maxn[1]<=y2)return a[k].sum;
        int ans=0;
        if(x1<=a[k].p[0]&&a[k].p[0]<=x2&&y1<=a[k].p[1]&&a[k].p[1]<=y2)ans+=a[k].w;
        ans+=query(a[k].c[0],x1,y1,x2,y2)+query(a[k].c[1],x1,y1,x2,y2);
        return ans;
    }
    int main()
    {
    	int opt,x1,y1,x2,y2,last=0,tot=0;
    	scanf("%*d");
    	while(scanf("%d",&opt)!=EOF&&opt!=3)
    	{
    		if(opt==1)
    		{
    			++tot,scanf("%d%d%d",&a[tot].p[0],&a[tot].p[1],&a[tot].w);
                a[tot].p[0]^=last,a[tot].p[1]^=last,a[tot].w^=last,a[tot].sum=a[tot].w;
                a[tot].maxn[0]=a[tot].minn[0]=a[tot].p[0];
                a[tot].maxn[1]=a[tot].minn[1]=a[tot].p[1];
                Insert(tot);
                if(tot%10000==0)root=build(1,tot,0);
    		}
    		else scanf("%d%d%d%d",&x1,&y1,&x2,&y2),x1^=last,y1^=last,x2^=last,y2^=last,printf("%d
    ",last=query(root,x1,y1,x2,y2));
    	}
    	return 0;
    }
    
  • 相关阅读:
    【内推面试分享】普通本科的蚂蚁金服校招面试经验分享,内附答案
    Json解析
    创建新的MessageBox窗口前,先关掉之前已经创建好的
    TcxCheckComboBox的使用
    Delphi调用C#的DLL
    StringGrid数据导出到Excel
    从Excel导入信息在StringGrid显示
    JS的修饰符
    局部变量和全局变量
    List注意啊
  • 原文地址:https://www.cnblogs.com/wljss/p/14969027.html
Copyright © 2011-2022 走看看