【34.25%】【BZOJ 2648】SJY摆棋子

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 2718  Solved: 931
[Submit][Status][Discuss]

2 3
1 1
2 3
2 1 2
1 3 3
2 4 2

1
2

kdtree可以过

Source

【题解】

int gujia_min(int rt)
{
int temp = 0;
for (int i = 0; i <= 1; i++)
{
temp += max(0, op.d[i]-t[rt].ma_x[i]);
temp += max(0, t[rt].mi_n[i] - op.d[i]);
}
return temp;
}

【代码】

#include <cstdio>
#include <algorithm>

using namespace std;

const int MAX_SIZE = 1500000;
const int MAXN = 509000;
const int INF = 2100000000;

struct point
{
int d[2];
int ma_x[2], mi_n[2], l, r;
};

point t[MAX_SIZE],p[MAXN],op;
int n, m,totn = 0,root,now,ans; //totn用于创建新的节点。

bool cmp(point a, point b)
{
if (a.d[now] < b.d[now])
return true;
return false;
}

void push_up(int rt)
{
int l = t[rt].l, r = t[rt].r;
for (int i = 0; i <= 1; i++)
{
if (l)
{
t[rt].ma_x[i] = max(t[l].ma_x[i], t[rt].ma_x[i]);
t[rt].mi_n[i] = min(t[l].mi_n[i], t[rt].mi_n[i]);
}
if (r)
{
t[rt].ma_x[i] = max(t[r].ma_x[i], t[rt].ma_x[i]);
t[rt].mi_n[i] = min(t[r].mi_n[i], t[rt].mi_n[i]);
}
}
}

int build(int begin, int end, int fx)
{
now = fx;
int m = (begin + end) >> 1;
nth_element(p + begin, p + m, p + end + 1, cmp);
int temp = ++totn; //新建的节点要保存下来。
for (int i = 0; i <= 1; i++)
{
t[temp].d[i] = p[m].d[i];
t[temp].ma_x[i] = t[temp].mi_n[i] = p[m].d[i];
}
if (begin < m)
t[temp].l = build(begin, m - 1, 1 - fx);
if (m < end)
t[temp].r = build(m + 1, end, 1 - fx);
push_up(temp);
return temp;
}

void input_data()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d%d", &p[i].d[0], &p[i].d[1]);
root = build(1, n, 0);
}

void insert(int &rt,int fx)
{
if (rt == 0)
{
rt = ++totn;
for (int i = 0; i <= 1; i++)
{
t[rt].d[i] = op.d[i];
t[rt].ma_x[i] = t[rt].mi_n[i] = op.d[i];
}
return;//这里的return不能省略。不然叶子节点也会执行push_up操作。
}
else
if (op.d[fx] < t[rt].d[fx])
insert(t[rt].l, 1 - fx);
else
insert(t[rt].r, 1 - fx);
push_up(rt);//因为插入了元素，修改了点。所以要更新ma_x,mi_n值。
}

int get_dis(point a, point b)
{
return abs(a.d[0] - b.d[0]) + abs(a.d[1] - b.d[1]);
}

int gujia_min(int rt)
{
int temp = 0;
for (int i = 0; i <= 1; i++)
{
temp += max(0, op.d[i]-t[rt].ma_x[i]);
temp += max(0, t[rt].mi_n[i] - op.d[i]);
}
return temp;
}

void query_min(int rt)
{
int dis = get_dis(t[rt], op);
ans = min(ans, dis);
int gl = INF, gr = INF;
int l = t[rt].l, r = t[rt].r;
if (l)
gl = gujia_min(l);
if (r)
gr = gujia_min(r);
if (gl < gr)
{
if (ans > gl)
query_min(l);
if (ans > gr)
query_min(r);
}
else
{
if (ans > gr)
query_min(r);
if (ans > gl)
query_min(l);
}
}

void output_ans()
{
for (int i = 1; i <= m; i++)
{
int cs;
scanf("%d%d%d", &cs, &op.d[0], &op.d[1]);
if (cs == 1)
insert(root,0);
else
if (cs == 2)
{
ans = INF;
query_min(root);
printf("%d\n", ans);
}
}
}

int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
output_ans();
return 0;
}

posted @ 2017-10-06 19:23  AWCXV  阅读(149)  评论(0编辑  收藏  举报