• bzoj2648 SJY摆棋子


    题目链接

    思路

    (KD-tree)模板题

    代码

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    #define ls TR[rt].ch[0]
    #define rs TR[rt].ch[1]
    const int N = 1000000 + 100,INF = 1e9;
    ll read() {
    	ll x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9') {
    		x=x*10+c-'0';
    		c=getchar();
    	}
    	return x*f;
    }
    struct node {
    	int ch[2],d[2],mx[2],mn[2];
    }TR[N],TMP,a[N];
    int n,m;
    int ans,root;
    int fx;
    bool cmp(const node &A,const node &B) {
    	return A.d[fx] < B.d[fx];
    }
    void up(int rt) {
    	for(int i = 0;i <= 1;++i) {
    		if(ls) TR[rt].mn[i] = min(TR[rt].mn[i],TR[ls].mn[i]),
    			TR[rt].mx[i] = max(TR[rt].mx[i],TR[ls].mx[i]);
    		if(rs) TR[rt].mn[i] = min(TR[rt].mn[i],TR[rs].mn[i]),
    			TR[rt].mx[i] = max(TR[rt].mx[i],TR[rs].mx[i]);
    	}
    }
    int build(int l,int r,int now) {
    	fx = now;
    	int mid = (l + r) >> 1;
    	nth_element(a + l,a + mid,a + r + 1,cmp);
    	TR[mid] = a[mid];
    	int rt = mid;
    	for(int i = 0;i <= 1;++i) TR[mid].mn[i] = TR[mid].mx[i] = TR[mid].d[i];
    		if(l < mid) ls = build(l,mid - 1,now ^ 1);
    		if(r > mid) rs = build(mid + 1,r,now ^ 1);
    		up(mid);
    		return mid;
    }
    void insert(int rt,int now) {
    	if(TMP.d[now] >= TR[rt].d[now]) {
    		if(rs) insert(rs,now ^ 1);
    		else {
    			rs = ++n;
    			TR[n] = TMP;
    			for(int i = 0;i <= 1;++i) TR[n].mn[i] = TR[n].mx[i] = TR[n].d[i];
    		}
    	}
    	else {
    		if(ls) insert(ls,now ^ 1);
    		else {
    			ls = ++n;
    			TR[n] = TMP;
    			for(int i = 0;i <= 1;++i) TR[n].mn[i] = TR[n].mx[i] = TR[n].d[i];
    		}
    	}
    	up(rt);
    }
    int dis(const node &A,const node &B) {
    	return abs(A.d[0] - B.d[0]) + abs(A.d[1] - B.d[1]);
    }
    int get(node A,node B) {
    	int ret = 0;
    	for(int i = 0;i <= 1;++i) ret += max(0,A.mn[i] - B.d[i]);
    	for(int i = 0;i <= 1;++i) ret += max(0,B.d[i] - A.mx[i]);
    	return ret;
    }
    void query(int rt,int now) {
    	int d = dis(TR[rt],TMP),dl = INF,dr = INF;
    	ans = min(ans,d);
    	if(ls) dl = get(TR[ls],TMP);
    	if(rs) dr = get(TR[rs],TMP);
    	if(dl < dr) {
    		if(dl < ans) query(ls,now ^ 1);
    		if(dr < ans) query(rs,now ^ 1);
    	}
    	else {
    		if(dr < ans) query(rs,now ^ 1);
    		if(dl < ans) query(ls,now ^ 1);
    	}
    }
    int Query(int x,int y) {
    	TMP.d[0] = x;TMP.d[1] = y;
    	ans = INF;
    	query(root,0);
    	return ans;
    }
    void Insert(int x,int y) {
    	TMP.d[0] = x;TMP.d[1] = y;
    	insert(root,0);
    }
    int main() {
    	// freopen("2648/17.in","r",stdin);
    	n = read(),m = read();
    	for(int i = 1;i <= n;++i) {
    		a[i].d[0] = read();a[i].d[1] = read();
    	}
    	root = build(1,n,0);
    	for(int i = 1;i <= m;++i) {
    		int opt = read(),x = read(),y = read();
    		if(opt == 1) Insert(x,y);
    		else printf("%d
    ",Query(x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    line
    同步fifo的verilogHDL设计实例
    在DE1-SOC上运行Linux
    DE1-SOC连接设定
    Tcl语言笔记之二
    Tcl语言笔记之一
    关于复位赋初值的问题
    Altera FPGA中的pin进一步说明
    Altera FPGA中的pin简介
    笔记之Cyclone IV第一卷第四章Cyclone IV器件中的嵌入式乘法器
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj2648.html
Copyright © 2020-2023  润新知