Codeforces 936E Iqea
Posted rddccd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于Codeforces 936E Iqea的主要内容,如果未能解决你的问题,请参考以下文章
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段
Codeforces 86C Genetic engineering(AC自动机+DP)