zoukankan      html  css  js  c++  java
  • 【bzoj 4066】 简单题

    题目

    显然这就是让我们在二维上数个点

    如果没有强制在线就随便做啦,扫描线+主席树应该是最好的选择

    但是现在强制在线并且卡了树套树的空间,于是只能上(kdt)

    我们还是维护一下每个子树分割出来的矩形的四个坐标

    查询的时候发现如果当前整个子树都被查询的矩形包含,我们就直接加入答案

    如果完全没有交,我们就直接退出

    否则我们判断一下是否要把当前子树的根加入答案,之后递归左右两边的子树就好了

    在随机数据下拥有一个(log)的美妙复杂度,但是卡卡就变成根号了

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||x>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const double alph=0.7;
    const int maxn=300005;
    struct Point{int x[2],w;}p[maxn],a[maxn];
    int l[maxn],r[maxn],sz[maxn],mx[maxn][2],mi[maxn][2],d[maxn],st[maxn];
    int n,m,cnt,top,rt,lst,op,num;
    inline int cmp(Point A,Point B) {return A.x[op]<B.x[op];}
    inline int newnode() {
    	if(top) return st[top--];
    	return ++cnt;
    }
    inline void pushup(int k) {
    	mi[k][0]=mx[k][0]=p[k].x[0];
    	mi[k][1]=mx[k][1]=p[k].x[1];
    	for(re int i=0;i<2;i++) {
    		if(l[k]) mx[k][i]=max(mx[k][i],mx[l[k]][i]),
    				 mi[k][i]=min(mi[k][i],mi[l[k]][i]);
    		if(r[k]) mx[k][i]=max(mx[k][i],mx[r[k]][i]),
    				 mi[k][i]=min(mi[k][i],mi[r[k]][i]);
    	}
    	sz[k]=sz[l[k]]+sz[r[k]]+1;
    	d[k]=d[l[k]]+d[r[k]]+p[k].w;
    }
    int build(int x,int y,int o) {
    	if(x>y) return 0;
    	int mid=x+y>>1,k=newnode();
    	op=o;std::nth_element(a+x,a+mid,a+y+1,cmp);p[k]=a[mid];
    	l[k]=build(x,mid-1,o^1),r[k]=build(mid+1,y,o^1);
    	pushup(k);return k;
    }
    void kill(int k) {
    	if(l[k]) kill(l[k]);
    	st[++top]=k;a[++num]=p[k];
    	if(r[k]) kill(r[k]);
    }
    inline int check(int k,int o) {
    	if(max(sz[l[k]],sz[r[k]])>sz[k]*alph)
    		return num=0,kill(k),build(1,num,o);
    	return k;
    }
    int ins(Point a,int k,int o) {
    	if(!k) {
    		k=newnode();p[k]=a;pushup(k);
    		return k;
    	}
    	if(a.x[o]<=p[k].x[o]) l[k]=ins(a,l[k],o^1);
    		else r[k]=ins(a,r[k],o^1);
    	pushup(k);return check(k,o);
    }
    inline int pd(int x,int y,int xx,int yy,int k) {
    	return (x<=mi[k][0]&&xx>=mx[k][0]&&y<=mi[k][1]&&yy>=mx[k][1]);
    }
    inline int chk(int x,int y,int xx,int yy,int k) {
    	return (mi[k][0]>xx||mx[k][0]<x||mi[k][1]>yy||mx[k][1]<y);
    }
    int query(int x,int y,int xx,int yy,int k) {
    	if(!k||chk(x,y,xx,yy,k)) return 0;
    	if(pd(x,y,xx,yy,k)) return d[k];
    	int now=0;
    	if(x<=p[k].x[0]&&xx>=p[k].x[0]&&y<=p[k].x[1]&&yy>=p[k].x[1]) now+=p[k].w;
    	if(pd(x,y,xx,yy,l[k])&&l[k]) now+=d[l[k]];else now+=query(x,y,xx,yy,l[k]);
    	if(pd(x,y,xx,yy,r[k])&&r[k]) now+=d[r[k]];else now+=query(x,y,xx,yy,r[k]);
    	return now;
    }
    int main() {
    	n=read();
    	int opt,x,y,xx,yy,val;
    	while(1) {
    		opt=read();
    		if(opt==1) {
    			x=read()^lst,y=read()^lst;val=read()^lst;
    			Point a;a.x[0]=x,a.x[1]=y,a.w=val;
    			rt=ins(a,rt,0);
    		}
    		if(opt==2) {
    			x=read()^lst,y=read()^lst,xx=read()^lst,yy=read()^lst;
    			lst=query(x,y,xx,yy,rt);
    			printf("%d
    ",lst);
    		}
    		if(opt==3) return 0;
    	}
    	return 0;
    }
    
  • 相关阅读:
    如何快速定位到DBGrid的某一行!!!急...
    说说设计模式~单件模式(Singleton)
    EF架构~终于自己架构了一个相对完整的EF方案
    .Net——实现IConfigurationSectionHandler接口定义处理程序处理自定义节点
    在LINQ中实现多条件联合主键LEFT JOIN
    从LINQ开始之LINQ to Objects(上)
    WPF控件模板和数据模板
    WPF的ListView控件自定义布局用法实例
    初步探讨WPF的ListView控件(涉及模板、查找子控件)
    LINQ技巧:如何通过多次调用GroupBy实现分组嵌套
  • 原文地址:https://www.cnblogs.com/asuldb/p/10755503.html
Copyright © 2011-2022 走看看