• bzoj 4066: 简单题 K-D树


    题目大意:

    http://www.lydsy.com/JudgeOnline/problem.php?id=4066

    题解

    我们把每次的修改操作都当作二维平面上多了一个权值点
    对于每组询问可以看做求一个矩形区域内的点权和
    所以我们用k-D Tree直接搜就好了

    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 160010;
    const int lim_siz = 2000;
    int split[maxn],now;
    int dem = 2;
    struct Node{
    	int pos[2],val;
    	int minn[2],maxx[2],sum;
    	Node *ch[2];
    	void update(){
    		for(int d=0;d<dem;++d) minn[d] = min(pos[d],min(ch[0]->minn[d],ch[1]->minn[d]));
    		for(int d=0;d<dem;++d) maxx[d] = max(pos[d],max(ch[0]->maxx[d],ch[1]->maxx[d]));
    		sum = val + ch[0]->sum + ch[1]->sum;
    	}
     
    }*null,*root,*op;
    Node T[maxn];
    inline bool cmp(const Node &a,const Node &b){
    	return a.pos[split[now]] < b.pos[split[now]];
    }
    inline void init(){
    	null = &T[0];
    	null->ch[0] = null->ch[1] = null;
    	null->val = 0;
    	for(int d=0;d<dem;++d){
    		null->pos[d] = 0;
    		null->minn[d] = 0x3f3f3f3f;
    		null->maxx[d] = -0x3f3f3f3f;
    	}root = null;
    }
    Node* build(int l,int r,int s){
    	if(l > r) return null;
    	int mid = (l+r)>> 1;
    	split[now = mid] = s % dem;
    	nth_element(T+l,T+mid,T+r+1,cmp);
    	Node *p = &T[mid];
    	p->ch[0] = build(l,mid-1,s+1);
    	p->ch[1] = build(mid+1,r,s+1);
    	p->update();return p;
    }
    int sav[maxn][2],sav_cnt,cnt;
    int val[maxn],cmd,X1,Y1,X2,Y2,x;
    int query(Node *p){
    	if(p == null) return 0;
    	if(p->minn[0] >= X1 && p->minn[1] >= Y1
    	&& p->maxx[0] <= X2 && p->maxx[1] <= Y2)
    		return p->sum;
    	else if(p->maxx[1] < Y1 || p->maxx[0] < X1 
    		 || p->minn[0] > X2 || p->minn[1] > Y2)
    		return 0;
    	if( p->pos[0] >= X1 && p->pos[1] >= Y1
    	&&  p->pos[0] <= X2 && p->pos[1] <= Y2)
    		return p->val + query(p->ch[0]) + query(p->ch[1]);
    	return query(p->ch[0]) + query(p->ch[1]);
    }
    int main(){
    	init();
    	int n;read(n);//read(n);
    	int lastans = 0;
    	while(1){
    		read(cmd);
    		if(cmd == 3) break;
    		if(cmd == 1){
    			read(X1);read(Y1);read(x);
    			X1 ^= lastans;Y1 ^= lastans;x ^= lastans;
    			sav[++sav_cnt][0] = X1;
    			sav[sav_cnt][1] = Y1;
    			val[sav_cnt] = x;
    			if(sav_cnt == lim_siz){
    				for(int i=1;i<=sav_cnt;++i){
    					T[cnt+i].minn[0] = T[cnt+i].maxx[0] = T[cnt+i].pos[0] = sav[i][0];
    					T[cnt+i].minn[1] = T[cnt+i].maxx[1] = T[cnt+i].pos[1] = sav[i][1];
    					T[cnt+i].val = val[i];
    				}root = build(1,cnt+=sav_cnt,1);
    				sav_cnt = 0;
    			}
    		}else{
    			read(X1);read(Y1);read(X2);read(Y2);
    			X1 ^= lastans;Y1 ^= lastans;
    			X2 ^= lastans;Y2 ^= lastans;
    			int ans = 0;
    			for(int i=1;i<=sav_cnt;++i){
    				if(sav[i][0] >= X1 && sav[i][1] >= Y1
    				&& sav[i][0] <= X2 && sav[i][1] <= Y2)
    					ans += val[i];
    			}
    			ans += query(root);
    			printf("%d
    ",lastans = ans);
    		}
    	}
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    Python小工具:统计代码行数
    计算机图形学复习(一)
    牛客多校训练第一场 J.Different Integers
    数据校验码概述
    数据库复习第二章
    数据库复习第一章
    自动化AC器(带界面版)
    ZOJ 3747 Attack on Titans
    Codeforces Round #245 (Div. 1) B. Working out
    HDU 6266 Hakase and Nano 【博弈论】
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6427220.html
Copyright © 2020-2023  润新知