Codeforces 936E Iqea

题目链接

首先把每一列看成一个点,这样子保证建出来是一棵树(yy一下就知道了)

然后构点分树。构点分树的时候维护每个格子到它的点分树上的祖先们的最近距离和对应的格子。

每个格子维护它管辖的范围内离它最近的黑点

update的时候更新所有祖先,注意更新答案时是vi = min(vi , da + abs(i - y)),这个part可以用李超线段树来维护

询问的时候暴跳祖先更新答案

  1 #include<cstdio>
  2 #include<vector>
  3 #include<algorithm>
  4 #include<map>
  5 #include<set>
  6 using namespace std;
  7 const int INF = 1e9 + 7;
  8 int n , q;
  9 struct point
 10 {
 11     int x,y;
 12 }p[300005];
 13 struct seg
 14 {
 15     int l,r;
 16     int vl , vr;
 17 }Node[300005 * 4];
 18 vector<int> E[300005]; 
 19 vector<int> G[300005]; 
 20 vector<int> d[300005];
 21 vector<int> pos[300005];
 22 bool vis[300005];
 23 int range[300005]; 
 24 int size[300005];
 25 int val[300005];
 26 int fa[300005];
 27 int gcnt = 0 , siz , minn , cen , num = 0;
 28 bool operator < (point a,point b)
 29 {
 30     if(a.x == b.x) return a.y < b.y;
 31     return a.x < b.x;
 32 }
 33 map<point,int> mp;
 34 map<point,int> mp2;
 35 set<int> s;
 36 bool cmp(point a,point b)
 37 {
 38     if(a.x == b.x) return a.y > b.y;
 39     return a.x < b.x;
 40 }
 41 inline void add(int u,int v)
 42 {
 43     E[u].push_back(v);E[v].push_back(u);
 44     return;
 45 }
 46 inline int max(int a,int b)
 47 {
 48     return a > b ? a : b;
 49 }
 50 void dfs(int f,int u)
 51 {
 52     size[u] = 1;
 53     int g = 0;
 54     for(int i = 0;i < E[u].size();i++){
 55         if(E[u][i] != f && !vis[E[u][i]]){
 56             dfs(u , E[u][i]);
 57             size[u] += size[E[u][i]];
 58             g = max(g , size[E[u][i]]);
 59         }
 60     }
 61     g = max(g , siz - size[u]);
 62     if(g < minn){
 63         minn = g;cen = u;
 64     }
 65     return;
 66 }
 67 void dfs2(int f,int u)
 68 {
 69     if(f == 0){for(int i = 0;i < G[u].size();i++) {d[G[u][i]].push_back(0);pos[G[u][i]].push_back(G[u][i]);}}
 70     else{
 71         for(int i = 0;i < G[u].size();i++){
 72             int ny = range[u] + (G[u].size() - i - 1), za , da;
 73             if(range[f] <= ny && ny <= range[f] + G[f].size() - 1) {za = G[f][G[f].size() - ny + range[f] - 1];da = 1;}
 74             else if(ny < range[f]){za = G[f][G[f].size() - 1];da = range[f] - ny + 1;}
 75             else {za = G[f][0];da = ny - (range[f] + G[f].size()) + 2;}
 76             d[G[u][i]].push_back(d[za][d[za].size() - 1] + da);
 77             pos[G[u][i]].push_back(pos[za][pos[za].size() - 1]);
 78         }
 79     }
 80     for(int i = 0;i < E[u].size();i++){
 81         if(E[u][i] != f && !vis[E[u][i]]) dfs2(u , E[u][i]);
 82     }
 83     return;
 84 }
 85 void solve(int f,int u)
 86 {
 87     minn = INF;
 88     dfs(0,u);
 89     vis[cen] = 1;fa[cen] = f;
 90     dfs2(0 , cen);
 91     int t = cen;
 92     for(int i = 0;i < E[t].size();i++){
 93         if(!vis[E[t][i]]){
 94             siz = size[E[t][i]];
 95             solve(t , E[t][i]);
 96         }
 97     }
 98     return;
 99 }
100 void build(int i,int l,int r)
101 {
102     Node[i].l = l , Node[i].r = r;
103     Node[i].vl = Node[i].vr = INF;
104     if(l == r) return;
105     build(i<<1 , l , (l + r)>>1);
106     build((i<<1)+1 , ((l + r)>>1) + 1 , r);
107     return;
108 }
109 int calc(bool q , int l , int vl , int pos)
110 {
111     if(vl == INF) return INF;
112     if(q) return vl + (pos - l);
113     return vl - (pos - l);
114 }
115 void Update(int i,int l,int r,int vl,int vr)
116 {
117     int mid = (Node[i].l + Node[i].r) >> 1;
118     if(l <= Node[i].l && r >= Node[i].r){
119         int tl = calc(vl <= vr , l , vl , Node[i].l) , tr = calc(vl <= vr , l , vl , Node[i].r);
120         int sl = tl - Node[i].vl , sr = tr - Node[i].vr;
121         if(sl <= 0 && sr <= 0){
122             Node[i].vl = tl , Node[i].vr = tr;
123             return;
124         }
125         if(sl >= 0 && sr >= 0) return;
126         if(abs(sl) < abs(sr)){
127             if(sr < 0) {Update(i<<1 , Node[i].l , Node[i].r , Node[i].vl , Node[i].vr); Node[i].vl = tl , Node[i].vr = tr;}
128             else {Update(i<<1 , l , r , vl , vr);}
129         }
130         else{
131             if(sl < 0) {Update((i<<1)+1 , Node[i].l , Node[i].r , Node[i].vl , Node[i].vr); Node[i].vl = tl , Node[i].vr = tr;}
132             else {Update((i<<1) + 1 , l , r , vl , vr);}
133         }
134     }
135     else{
136         if(l <= mid) Update(i<<1 , l , r , vl , vr);
137         if(r > mid) Update((i<<1) + 1 , l , r , vl , vr);
138     }
139     return;
140 }
141 int Query(int i,int pos)
142 {
143     if(Node[i].l == Node[i].r) return Node[i].vl;
144     int mid = (Node[i].l + Node[i].r) >> 1;
145     int ans = calc(Node[i].vl <= Node[i].vr , Node[i].l , Node[i].vl , pos);
146     if(pos <= mid) return min(Query(i<<1 , pos) , ans);
147     else return min(ans , Query((i<<1) + 1 , pos));
148 }
149 void update(int x,int y)
150 {
151     map<point,int>::iterator it = mp.find(point{x , y});
152     int u = (it->second);
153     it = mp2.find(point{x , y});
154     int v = (it->second);
155     int i = d[v].size() - 1;
156     while(u != 0){
157         int dis = d[v][i];
158         if(p[pos[v][i]].y != range[u]) Update(1 , pos[v][i] + 1 , G[u][G[u].size() - 1] , dis + 1 , dis + G[u][G[u].size() - 1] - pos[v][i]);
159         Update(1 , G[u][0] , pos[v][i] , dis + pos[v][i] - G[u][0], dis);
160         u = fa[u];
161         i--;
162     }
163     return;
164 }
165 int query(int x,int y)
166 {
167     if(!num) return -1;
168     map<point,int>::iterator it = mp.find(point{x , y});
169     int u = (it->second);
170     it = mp2.find(point{x , y});
171     int v = (it->second);
172     int i = d[v].size() - 1;
173     int ans = INF;
174     while(u != 0){
175         int gg;
176         ans = min(ans , (gg = Query(1 , pos[v][i])) + d[v][i]);
177         i--;
178         u = fa[u];
179     }
180     return ans;
181 }
182 int main()
183 {
184     scanf("%d",&n);
185     for(int i = 1;i <= n;i++){
186         scanf("%d%d",&p[i].x,&p[i].y);val[i] = INF;
187     }
188     sort(p+1,p+n+1,cmp);
189     for(int i = 1;i <= n;i++){
190         if(p[i].x != p[i - 1].x || p[i].y != p[i - 1].y - 1){++gcnt;s.clear();}
191      //   printf("%d %d %d\n",p[i].x,p[i].y,i);
192         G[gcnt].push_back(i);
193         map<point,int>::iterator it = mp.find(point{p[i].x - 1 , p[i].y});
194         if(it != mp.end()){
195             if(s.find(it->second) == s.end()){
196                 add(gcnt , it->second);
197                 s.insert(it->second);
198             }
199         }
200         mp.insert(pair<point,int>{p[i] , gcnt});
201         mp2.insert(pair<point,int>{p[i] , i});
202         range[gcnt] = p[i].y;
203     }
204     build(1,1,n);
205     siz = gcnt;
206     solve(0,1);
207     int op , x , y;
208     scanf("%d",&q);
209     while(q--){
210         scanf("%d%d%d",&op,&x,&y);
211         if(op == 1){update(x , y);num = 1;}
212         else printf("%d\n",query(x , y));
213     }
214     return 0;
215 }
View Code

 

posted @ 2018-05-15 12:28  Sugar!  阅读(501)  评论(0编辑  收藏  举报