• [CQOI2016]K远点对


    嘟嘟嘟


    做过[国家集训队]JZPFAR这道题的话,这题就不难了。


    我们维护一个长度为(k)的小根堆,在加入第(i)个点之前,用([1, i - 1])这些点离点(i)的距离更新答案。这样也能保证每一对点之间的距离一定只算了一次。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<stack>
    #include<queue>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 1e5 + 5;
    const int SIZE = 5000;
    inline ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), last = ' ';
    	while(!isdigit(ch)) last = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(last == '-') ans = -ans;
    	return ans;
    }
    inline void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    int n, K, Dim;
    priority_queue<ll, vector<ll>, greater<ll> > q;
    struct Tree
    {
    	int ch[2];
    	ll d[2], Min[2], Max[2];
    	In bool operator < (const Tree& oth)const
    	{
    		return d[Dim] < oth.d[Dim];
    	}
    }t[maxn], a[maxn];
    int root, tcnt = 0, cnt = 0;
    In void pushup(int now)
    {
    	for(int i = 0; i < 2; ++i)
    	{
    		if(t[now].ch[0])
    		{
    			t[now].Min[i] = min(t[now].Min[i], t[t[now].ch[0]].Min[i]);
    			t[now].Max[i] = max(t[now].Max[i], t[t[now].ch[0]].Max[i]);
    		}
    		if(t[now].ch[1])
    		{
    			t[now].Min[i] = min(t[now].Min[i], t[t[now].ch[1]].Min[i]);
    			t[now].Max[i] = max(t[now].Max[i], t[t[now].ch[1]].Max[i]);
    		}
    	}
    }
    In void new_node(int& now, Tree a)
    {
    	t[now = ++tcnt] = a;
    	for(int i = 0; i < 2; ++i)
    	{
    		t[now].ch[i] = 0;
    		t[now].Min[i] = t[now].Max[i] = t[now].d[i];
    	}
    }
    In void build(int& now, int L, int R, int d)
    {
    	if(L > R) return;
    	int mid = (L + R) >> 1;
    	Dim = d;
    	nth_element(a + L, a + mid, a + R + 1);
    	new_node(now, a[mid]);
    	build(t[now].ch[0], L, mid - 1, d ^ 1);
    	build(t[now].ch[1], mid + 1, R, d ^ 1);
    	pushup(now);
    }
    In void insert(int& now, Tree a, int d)
    {
    	if(!now) {new_node(now, a); return;}
    	if(a.d[d] <= t[now].d[d]) insert(t[now].ch[0], a, d ^ 1);
    	else insert(t[now].ch[1], a, d ^ 1);
    	pushup(now);
    }
    In ll dis(int now, ll * d)
    {
    	ll ret = 0;
    	for(int i = 0; i < 2; ++i) ret += (d[i] - t[now].d[i]) * (d[i] - t[now].d[i]);
    	return ret;
    }
    In ll price(int now, ll* d)
    {
    	ll ret = 0;
    	for(int i = 0; i < 2; ++i)
    	{
    		ll Max = max(abs(t[now].Min[i] - d[i]), abs(t[now].Max[i] - d[i]));
    		ret += Max * Max;
    	}
    	return ret;
    }
    In void query(int now, ll* d)
    {
    	if(!now) return;
    	ll tp = dis(now, d);
    	if(tp > q.top()) q.pop(), q.push(tp);
    	ll disL = price(t[now].ch[0], d), disR = price(t[now].ch[1], d);
    	if(disL < disR) swap(t[now].ch[0], t[now].ch[1]), swap(disL, disR);
    	if(disL > q.top()) query(t[now].ch[0], d);
    	if(disR > q.top()) query(t[now].ch[1], d);
    }
    
    int main()
    {
    	n = read(); K = read();
    	for(int i = 1; i <= K; ++i) q.push(-1);
    	for(int i = 1; i <= n; ++i)
    	{
    		a[++cnt].d[0] = read(), a[cnt].d[1] = read();
    		query(root, a[cnt].d);
    		if(cnt % SIZE == 0) 
    		{
    			for(int i = 1; i <= tcnt; ++i) t[i].ch[0] = t[i].ch[1] = 0;
    			tcnt = 0;
    			build(root, 1, cnt, 0);
    		}
    		else insert(root, a[cnt], 0);
    	}
    	write(q.top()), enter;
    	return 0;
    }
    
  • 相关阅读:

    HttpClient发送get/post请求
    maven创建ssm项目依赖(pom.xml文件)
    java的Scanner类总结
    java多线程总结
    java跨域问题
    Idea打包项目war并且发布到服务器
    Mybatis入门案例之增删改查
    springMVC中的@RequestBody和@ResponseBody以及@RequestParam
    Gson解析json
  • 原文地址:https://www.cnblogs.com/mrclr/p/10283306.html
Copyright © 2020-2023  润新知