bzoj2716 [Violet 3]天使玩偶

2716: [Violet 3]天使玩偶

Time Limit: 80 Sec  Memory Limit: 128 MB
Submit: 2160  Solved: 936
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

100 100
81 23
27 16
52 58
44 24
25 95
34 2
96 25
8 14
97 50
97 18
64 3
47 22
55 28
89 37
75 45
67 22
90 8
65 45
68 93
87 8
61 45
69 72
38 57
58 76
45 34
88 54
27 8
35 34
70 81
25 24
97 97
4 43
39 38
82 68
27 58
2 21
92 88
96 70
97 29
14 53
6 42
1 2
35 84
64 88
63 57
53 40
82 59
49 56
75 72
29 30
50 1
40 83
52 94
22 35
39 1
94 88
89 96
79 46
33 75
31 42
33 95
6 83
90 66
37 54
35 64
17 66
48 37
30 8
95 51
3 51
90 33
29 48
94 78
53 7
1 26
73 35
18 33
99 78
83 59
23 87
4 17
53 91
98 3
54 82
85 92
77 8
56 74
4 5
63 1
26 8
42 15
48 98
27 11
70 98
36 9
78 92
34 40
42 82
64 83
75 47
2 51 55
1 7 62
2 21 62
1 36 39
1 35 89
1 84 15
2 19 24
1 58 53
2 52 34
1 98 49
1 4 100
1 17 25
1 30 56
1 69 43
2 57 23
2 23 13
1 98 25
2 50 27
1 84 63
2 84 81
2 84 77
1 60 23
2 15 27
1 9 51
1 31 11
1 96 56
2 20 85
1 46 32
1 60 88
2 92 48
1 68 5
2 90 17
1 16 46
2 67 5
2 29 83
1 84 70
2 68 27
1 99 33
2 39 89
2 38 28
1 42 3
1 10 60
2 56 29
2 12 60
2 46 51
2 15 73
1 93 42
1 78 82
1 66 20
1 46 17
2 48 5
1 59 61
1 87 59
2 98 72
1 49 3
2 21 10
1 15 4
1 48 14
2 67 75
2 83 77
1 88 65
2 100 93
2 58 83
1 29 80
2 31 88
2 92 94
1 96 66
1 61 82
2 87 24
1 64 83
1 28 87
2 72 90
2 7 3
1 86 3
2 26 53
2 71 2
2 88 24
1 69 60
1 92 44
2 74 94
1 12 78
2 1 2
1 4 73
1 58 5
1 62 14
2 64 58
2 39 45
1 99 27
1 42 21
1 87 2
2 16 98
2 17 21
2 41 20
1 46 72
1 11 62
2 68 29
1 64 66
2 90 42
2 63 35
1 64 71

Sample Output

3
8
6
7
7
6
6
12
11
4
5
6
8
1
7
6
4
9
2
2
8
9
6
4
7
5
8
7
5
5
5
7
7
5
6
6
8
6
0
2
7
12
4
2
8
3
10

HINT

 

 

Source

分析:只涉及到修改和查询操作,并且允许离线,修改之间互相独立,可以用cdq分治来做.
          不好处理的是如何求最近距离,绝对值不好弄.那么考虑将绝对值去掉,分四种情况讨论,每次相当于把坐标系旋转90°,然后统计在询问的点左下方的点中x'+y'最大的,答案是x+y - (x' + y'),可以利用树状数组维护最大值.那么这就和三维偏序问题差不多了:时间,x,y.利用cdq分治处理时间,对x排序,在y上用树状数组维护≤y的最大x'+y'.
           比较容易出错的是如果树状数组中查询的max为0,说明没有点在当前点的左下方,需要返回-inf!!!因为一个点到自身的距离不能是它自己的x+y.
           最后80s卡时过了,别人都以为我在卡评测,结果突然蹦出一个AC233.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 1000010,inf = 0x7ffffff;
int n,m,maxx,maxy,ans[maxn],cnt,c[maxn];

struct node
{
    int x,y,id,z,ansid;
} e[maxn],p[maxn],t[maxn];

bool cmp(node a,node b)
{
    if (a.x == b.x && a.y == b.y)
        return a.id < b.id;
    if (a.x == b.x)
        return a.y < b.y;
    return a.x < b.x;
}

void add(int x,int v)
{
    while (x <= maxy)
    {
        c[x] = max(c[x],v);
        x += x & (-x);
    }
}

void clea(int x)
{
    while (x <= maxy)
    {
        c[x] = 0;
        x += x & (-x);
    }
}

int query(int x)
{
    int res = 0;
    while (x)
    {
        res = max(res,c[x]);
        x -= x & (-x);
    }
    return res == 0 ? -inf: res;
}

void solve(int l,int r)
{
    if (l == r)
        return;
    int mid = (l + r) >> 1;
    for (int i = l; i <= r; i++)
    {
        if (p[i].id <= mid && p[i].z == 1)
            add(p[i].y,p[i].x + p[i].y);
        else if (p[i].id > mid && p[i].z == 2)
            ans[p[i].ansid] = min(ans[p[i].ansid],p[i].x + p[i].y - query(p[i].y));
    }
    for (int i = l; i <= r; i++)
    {
        if (p[i].id <= mid && p[i].z == 1)
            clea(p[i].y);
    }
    int L = l,R = mid + 1;
    for (int i = l; i <= r; i++)
    {
        if (p[i].id <= mid)
            t[L++] = p[i];
        else
            t[R++] = p[i];
    }
    for (int i = l; i <= r; i++)
        p[i] = t[i];
    solve(l,mid),solve(mid + 1,r);
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d",&e[i].x,&e[i].y);
        e[i].x++;
        e[i].y++;
        maxx = max(maxx,e[i].x);
        maxy = max(maxy,e[i].y);
        e[i].id = i;
        e[i].z = 1;
    }
    for (int i = n + 1; i <= n + m; i++)
    {
        scanf("%d%d%d",&e[i].z,&e[i].x,&e[i].y);
        e[i].x++;
        e[i].y++;
        if (e[i].z == 2)
        {
            ans[++cnt] = inf;
            e[i].ansid = cnt;
        }
        maxx = max(maxx,e[i].x);
        maxy = max(maxy,e[i].y);
        e[i].id = i;
    }
    maxx++;
    maxy++;
    for (int i = 1; i <= n + m; i++)
        p[i] = e[i];
    sort(p + 1,p + 1 + n + m,cmp);
    solve(1,n + m);

    for (int i = 1; i <= n + m; i++)
    {
        p[i] = e[i];
        p[i].x = maxx - p[i].x;
    }
    sort(p + 1,p + 1 + n + m,cmp);
    solve(1,n + m);

    for (int i = 1; i <= n + m; i++)
    {
        p[i] = e[i];
        p[i].y = maxy - p[i].y;
    }
    sort(p + 1,p + 1 + n + m,cmp);
    solve(1,n + m);

    for (int i = 1; i <= n + m; i++)
    {
        p[i] = e[i];
        p[i].x = maxx - p[i].x;
        p[i].y = maxy - p[i].y;
    }
    sort(p + 1,p + 1 + n + m,cmp);
    solve(1,n + m);
    for (int i = 1; i <= cnt; i++)
        printf("%d\n",ans[i]);

    return 0;
}

 

posted @ 2018-01-06 09:51  zbtrs  阅读(220)  评论(0编辑  收藏  举报