bzoj2716: [Violet 3]天使玩偶

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

 


见到样例的我眼泪掉下来(っ °Д °;)っ
偷偷瞄了眼题解2333,再加上自己YY终于做出来了~
首先是简化问题
针对一个询问点(a,b),我们可以只考虑x<=a&&y<=b的点,之后再通过翻转操作做4遍就好了~
那么当上述条件满足时,就变成了查询 时间在此时之前中所有x<=a&&y<=b的点中的max{x+y}了
有点像三维偏序哈
那么按照时间分治,只需要统计左区间对右区间的影响,扫描线加树状数组就好了~
在做的时候WA了。。。发现树状数组不能只赋成0,要赋成-inf。。。
然后被卡常。。所以加了“40行优化”hhh
但是bzoj原码上过了,真是神奇
最后被洛谷上的坑爹hack数据卡了,人家本来是要卡kdtree却卡住了我55555(kdtree是啥,能吃吗
一看是有0在树状数组上修改(淦,这个老忘(ノ`Д)ノ
还是在这里给上能过bzoj的码吧
 1 #include
 2 #include
 3 #include
 4 #define maxw 1000006
 5 using namespace std;
 6 int n,m,cnt;
 7 struct point{
 8     int t,x,y,id;
 9 }a[1000005],b[1000005];
10 int ans[1000005],c[maxw];
11 void add(int x,int val){while(x<=1000000){c[x]=max(c[x],val);x+=(x&(-x));}}
12 int query(int x){int ans=-1000006;while(x){ans=max(ans,c[x]);x-=(x&(-x));}return ans;}
13 void clear(int x){while(x<=1000000){c[x]=-1000006;x+=(x&(-x));}}
14 bool cmp(point A,point B){if(A.x==B.x)return A.treturn A.x<B.x;}
15 void fresh(){
16     sort(b+1,b+1+cnt,cmp);
17     for(int i=1;i<=cnt;i++)
18     if(b[i].t==1)add(b[i].y,b[i].x+b[i].y);
19     else ans[b[i].id]=min(ans[b[i].id],b[i].x+b[i].y-query(b[i].y));
20     for(int i=1;i<=cnt;i++)if(b[i].t==1)clear(b[i].y);
21 }
22 void solve(int l,int r){
23     if(l==r)return;
24     int mid=(l+r)/2;
25     solve(l,mid),solve(mid+1,r);
26     cnt=0;
27     for(int i=l;i<=mid;i++)
28     if(a[i].t==1)b[++cnt]=a[i];
29     for(int i=mid+1;i<=r;i++)
30     if(a[i].t==2)b[++cnt]=a[i];
31     sort(b+1,b+cnt+1,cmp);
32     for(int i=1;i<=cnt;i++)
33     if(b[i].t==1)add(b[i].y,b[i].x+b[i].y);
34     else ans[b[i].id]=min(ans[b[i].id],b[i].x+b[i].y-query(b[i].y));
35     for(int i=l;i<=mid;i++)
36     if(a[i].t==1)clear(a[i].y);
37 }
38 int main(){
39     scanf("%d%d",&n,&m);
40     for(int i=1;i<=n;i++){
41         scanf("%d%d",&b[i].x,&b[i].y);
42         b[i].t=1;
43     }
44     cnt=n;
45     for(int i=1;i<=m;i++){
46         scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].y);
47         a[i].id=i;
48         if(a[i].t==2)b[++cnt]=a[i];
49     }
50     memset(ans,0x3f,sizeof(ans));
51      
52     memset(c,128,sizeof(c));
53     fresh();
54     for(int i=1;i<=cnt;i++) b[i].x=1000000-b[i].x;
55     fresh();
56     for(int i=1;i<=cnt;i++) b[i].y=1000000-b[i].y;
57     fresh();
58     for(int i=1;i<=cnt;i++) b[i].x=1000000-b[i].x;
59     fresh();
60      
61      
62     solve(1,m);
63     for(int i=1;i<=m;i++) a[i].x=1000000-a[i].x;
64     solve(1,m);
65     for(int i=1;i<=m;i++) a[i].y=1000000-a[i].y;
66     solve(1,m);
67     for(int i=1;i<=m;i++) a[i].x=1000000-a[i].x;
68     solve(1,m);
69     for(int i=1;i<=m;i++)
70     if(a[i].t==2){
71         printf("%d\n",ans[a[i].id]);
72     }
73     return 0;
74 }
View Code

 

 

转载于:https://www.cnblogs.com/2017SSY/p/10201683.html

你可能感兴趣的:(bzoj2716: [Violet 3]天使玩偶)