您的位置:首页 > 其它

bzoj 2716 [Violet 3]天使玩偶 【CDQ分治】

2017-12-25 11:34 411 查看
 KD-tree可做,但是我不会暂时不考虑

大意:在二维平面内,给定n个点,m个操作。操作A:加入一个点;操作B:询问一个点与平面上加入的点的最近距离

不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T

把初始存在的点也看成加点操作

首先,曼哈顿距离取绝对值很烦,所以我们可以通过转坐标,把左上 右上 左下 右下通过转坐标都变成左下,最后取个min即可。于是对于(x,y)左下的点(x1,y1),dis=x-x1+y-y1=(x+y)-(x1+y1),用树状数组维护前缀最小值x1+y1。

按时间序排列,时间序 x y 三维偏序做CDQ分治即可

1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 using namespace std;
5 const int N=1000005,inf=1e9;
6 int n,m,maxx,ans
;
7 struct BIT
8 {
9     int c
;
10     int lb(int x)
11     {
12         return x&(-x);
13     }
14     void update(int x,int d)
15     {
16         for(int i=x;i<=maxx;i+=lb(i))
17             c[i]=max(c[i],d);
18     }
19     int ques(int x)
20     {
21         int ret=0;
22         for(int i=x;i>=1;i-=lb(i))
23             ret=max(ret,c[i]);
24         return ret;
25     }
26     void clear(int x)
27     {
28         for(int i=x;i<=maxx;i+=lb(i))
29             c[i] = 0;
30     }
31 }bit;
32 struct qwe
33 {
34     int x,y,k,id;
35     bool operator < (const qwe& rhs) const
36     {
37         if(x != rhs.x)
38             return x < rhs.x;
39         return id < rhs.id;
40     }
41 }a
;
42 struct CDQ
43 {
44     int n;
45     qwe T
;
46     void init(int n)
47     {
48         this->n=n;
49         sort(a+1,a+n+1);
50     }
51     void solve(int L, int R)
52     {
53         if(L>=R)
54             return;
55         int M=(L+R)>>1;
56         int p=L,q=M+1;
57         for(int i=L;i<=R;i++)
58             if(a[i].id<=M)
59                 T[p++]=a[i];
60             else
61                 T[q++]=a[i];
62         for(int i=L;i<=R;i++)
63             a[i]=T[i];
64         solve(L,M);
65         solve(M+1,R);
66         int i=M+1,j=L;
67         for(;i<=R;i++)
68             if(a[i].k==2)
69             {
70                 for(;j<=M&&a[j].x<=a[i].x;j++)
71                     if(a[j].k==1)
72                         bit.update(a[j].y,a[j].x+a[j].y);
73                 int t=bit.ques(a[i].y);
74                 if(t)
75                     ans[a[i].id]=min(ans[a[i].id],a[i].x+a[i].y-t);
76             }
77         for(int i=L;i<j;i++)
78             if(a[i].k==1)
79                 bit.clear(a[i].y);
80         merge(a+L,a+M+1,a+M+1,a+R+1,T+L);
81         for(int i=L;i<=R;i++)
82             a[i]=T[i];
83     }
84 }cdq;
85 int read()
86 {
87     int r=0;
88     char p=getchar();
89     while(p>'9'||p<'0')
90         p=getchar();
91     while(p>='0'&&p<='9')
92     {
93         r=r*10+p-48;
94         p=getchar();
95     }
96     return r;
97 }
98 int main()
99 {
100     n=read(),m=read();
101     for(int i=1;i<=n;i++)
102     {
103         a[i].x=read()+1;
104         a[i].y=read()+1;
105         a[i].id=i;
106         a[i].k=1;
107         maxx=max(maxx,max(a[i].x,a[i].y));
108     }
109     for(int i=n+1;i<=n+m;i++)
110     {
111         a[i].k=read();
112         a[i].x=read()+1;
113         a[i].y=read()+1;
114         a[i].id=i;
115         maxx=max(maxx,max(a[i].x,a[i].y));
116     }
117     maxx++;
118     n+=m;
119     for(int i=1;i<=n;i++)
120         ans[i]=inf;
121     cdq.init(n);
122     cdq.solve(1,n);
123     for(int i=1;i<=n;i++)
124         a[i].x=maxx-a[i].x;
125     cdq.init(n);
126     cdq.solve(1,n);
127     for(int i=1;i<=n;i++)
128         a[i].y=maxx-a[i].y;
129     cdq.init(n);
130     cdq.solve(1,n);
131     for(int i=1;i<=n;i++)
132         a[i].x=maxx-a[i].x;
133     cdq.init(n);
134     cdq.solve(1,n);
135     for(int i=1;i<=n;i++)
136         if(ans[i]!=inf)
137             printf("%d\n",ans[i]);
138     return 0;
139 }

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: