2716 [Violet 3] 天使玩偶

@(BZOJ)[CDQ分治]
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

Solution

4 * CDQ分治
細節不要寫錯
這份代碼是TLE的, 原因貌似是常數過大QAQ
假如讀者有在代碼中發現任何問題, 懇請告知, 筆者將感激不盡.

#include<cstdio>
#include<cctype>
#include<climits>
#include<cstring>
#include<algorithm> 
using namespace std;
 
inline int read()
{
    int x = 0, flag = 1;
    char c;
    while(! isdigit(c = getchar()))
        if(c == '-')
            flag *= - 1;
    while(isdigit(c))
        x = x * 10 + c - '0', c = getchar();
    return x * flag;
}
 
void println(int x)
{
    if(x < 0)
        putchar('-'), x *= - 1;
    if(x == 0)
        putchar('0');
    int ans[1 << 4], top = 0;
    while(x)
        ans[top ++] = x % 10, x /= 10;
    for(; top; top --)
        putchar(ans[top - 1] + '0');
    putchar('
');
}
 
const int N = 1 << 19, M = 1 << 19;
const int LIM = 1 << 20;
 
int n, m;
 
struct vertex 
{
    int x, y, opt, ID, time;
    
    inline friend bool operator <= (vertex a, vertex b)
    {
        if(a.x == b.x)
            return a.opt <= b.opt;
        return a.x <= b.x;
    }
}a[N + M], b[N + M], tmp[N + M];
 
int ans[M];
 
int T[LIM << 2];
 
void modify(int u, int L, int R, int p, int x)
{
    if(L + 1 == R)
    {
        T[u] = x;
        return;
    }
     
    int mid = L + R >> 1;
     
    if(p < mid)
        modify(u << 1, L, mid, p, x);
    else
        modify(u << 1 | 1, mid, R, p, x); 
        
    T[u] = max(T[u << 1], T[u << 1 | 1]);
}
 
int query(int u, int L, int R, int p)
{
    if(p + 1 >= R)
        return T[u];
     
    int mid = L + R >> 1;
     
    if(p < mid)
        return query(u << 1, L, mid, p);
    else
        return max(T[u << 1], query(u << 1 | 1, mid, R, p));
}
 
void cdq(int L, int R)
{
    if(L + 1 >= R) 
        return;
         
    int mid = L + R >> 1;
     
    cdq(L, mid), cdq(mid, R);
    
    for(int i = L; i < R; i ++)
    	tmp[i] = b[i];
    
    int p1 = L, p2 = mid, p = L;
    
    while(p1 < mid && p2 < R)
    {
    	if(b[p1] <= b[p2])
    		tmp[p ++] = b[p1 ++];
    	else
    		tmp[p ++] = b[p2 ++];
    }
    
    while(p1 < mid)
    	tmp[p ++] = b[p1 ++];
    	
    while(p2 < R)
    	tmp[p ++] = b[p2 ++];
    
    for(int i = L; i < R; i ++)
    	b[i] = tmp[i];
     
    for(int i = L; i < R; i ++)
    {
        if(b[i].ID < mid && ! b[i].opt)
            modify(1, 0, LIM, b[i].y, b[i].x + b[i].y);
        else if(b[i].ID >= mid && b[i].opt)
        {
        	int tmp = query(1, 0, LIM, b[i].y);	//注意要特判 
        	
        	if(tmp)
            	ans[b[i].time] = min(ans[b[i].time], b[i].x + b[i].y - tmp);
        }
    }
     
    for(int i = L; i < R; i ++)
        if(b[i].ID < mid && ! b[i].opt)
            modify(1, 0, LIM, b[i].y, 0);
}
 
void cdqSolve1()
{
    for(int i = 0; i < n + m; i ++)
        b[i] = a[i];
        
    cdq(0, n + m);
}
 
void cdqSolve2()
{
    for(int i = 0; i < n + m; i ++)
        b[i] = a[i], b[i].y = LIM - a[i].y;
        
    cdq(0, n + m);
}
 
void cdqSolve3()
{
    for(int i = 0; i < n + m; i ++)
        b[i] = a[i], b[i].x = LIM - a[i].x, b[i].y = LIM - a[i].y;
        
    cdq(0, n + m);
}
 
void cdqSolve4()
{
    for(int i = 1; i <= n + m; i ++)
        b[i] = a[i], b[i].x = LIM - a[i].x;
        
    cdq(0, n + m);
}
 
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("BZOJ2716.in", "r", stdin);
    freopen("BZOJ2716.out", "w", stdout);
    #endif
     
    n = read(), m = read();
    
    for(int i = 0; i < n; i ++)
        a[i].x = read() + 1, a[i].y = read() + 1, a[i].opt = 0, a[i].ID = i, a[i].time = - 1;
        
    for(int i = 0; i < m; i ++)
        a[n + i].opt = read() - 1, a[n + i].x = read() + 1, a[n + i].y = read() + 1, a[n + i].ID = i + n, a[n + i].time = i;
     
    memset(ans, 127, sizeof(ans));
    memset(T, 0, sizeof(T)); 
     
    cdqSolve1(), cdqSolve2(), cdqSolve3(), cdqSolve4();
     
    for(int i = 0; i < m; i ++)
        if(a[i + n].opt)
            println(ans[i]);
}
原文地址:https://www.cnblogs.com/ZeonfaiHo/p/6498308.html