BZOJ2157 旅行 模拟
题目内容:
Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。
题目分析:
一道码农题,最难的地方在于如何判断输入的是哪个操作,所以要深刻掌握switch,下面我来讲讲switch的用法。
switch的主要结构是:
switch(a){ case x:{......;break;} case y:{......;break;} default:{.......} }
值得注意的是case可以写任意多个且不能像if那样进行大于小于等的比较,所以switch的用处没有if大,而且switch可以完全用if代替,但是switch可以更方便地判断数字是否是这个并且作出操作。考虑到编程习惯,所以switch中case后面的括号是可以省略的。
题目代码:
1 #include<bits/stdc++.h> 2 #define SUM t[now].sum 3 #define MIN t[now].minn 4 #define MAX t[now].maxx 5 using namespace std; 6 struct edge{ 7 int to,w; 8 }; 9 const int INF = 120000; 10 const int maxn = 320000; 11 vector <edge> g[maxn]; 12 int d[maxn],arr[maxn],fa[maxn],son[maxn],head[maxn],sz[maxn],num[maxn],dep[maxn]; 13 int to_fa[maxn],fto_fa[maxn]; 14 struct ed{int from,to;}; 15 vector <ed> edges; 16 void dfs1(int now,int f,int d){ 17 arr[now] = 1; 18 dep[now] = d; 19 fa[now] = f; 20 sz[now] = 1; 21 int maxx = 0; 22 for(int i=0;i<g[now].size();i++){ 23 if(arr[g[now][i].to]){ 24 to_fa[now] = i; 25 continue; 26 } 27 fto_fa[g[now][i].to] = i; 28 dfs1(g[now][i].to,now,d+1); 29 sz[now] += sz[g[now][i].to]; 30 if(sz[g[now][i].to] > maxx){ 31 maxx = sz[g[now][i].to]; 32 son[now] = g[now][i].to; 33 } 34 } 35 } 36 37 int a[220000]; 38 int bh = 0; 39 40 void dfs2(int now,int h){ 41 arr[now] = 1; 42 head[now] = h; 43 for(int i=0;i<g[now].size();i++){ 44 if(g[now][i].to == son[now]&&!arr[g[now][i].to]){ 45 num[now] = ++bh; 46 a[bh] = g[now][i].w; 47 dfs2(g[now][i].to,h); 48 break; 49 } 50 } 51 for(int i=0;i<g[now].size();i++){ 52 if(g[now][i].to != son[now] && arr[g[now][i].to]==0){ 53 dfs2(g[now][i].to,g[now][i].to); 54 } 55 } 56 } 57 struct node{ 58 int sum,minn,maxx; 59 int f; 60 }t[1200000]; 61 void push_down(int); 62 void push_up(int now){ 63 if(t[now].f)push_down(now); 64 if(t[now * 2].f) push_down(now*2); 65 if(t[now*2+1].f)push_down(now*2+1); 66 SUM = t[now * 2].sum + t[now * 2 + 1].sum; 67 MIN = min(t[now * 2].minn,t[now*2+1].minn); 68 MAX = max(t[now*2].maxx,t[now*2+1].maxx); 69 } 70 71 void build_tree(int l,int r,int now){ 72 if(l == r){ 73 SUM = MAX = MIN = a[l]; 74 return; 75 } 76 int mid = (l+r) >> 1; 77 build_tree(l,mid,now * 2); 78 build_tree(mid+1,r,now * 2 + 1); 79 push_up(now); 80 } 81 82 void push_down(int now){ 83 SUM = -SUM; 84 swap(MIN,MAX); 85 MIN = -MIN; 86 MAX = -MAX; 87 t[now * 2].f ^= 1; 88 t[now * 2 + 1].f ^=1; 89 t[now].f = 0; 90 } 91 92 struct ask{ 93 int u,v,dir; 94 }A[120000]; 95 int pre[120000]; 96 struct point{ 97 int dis,num; 98 }; 99 vector <point> lca[120000]; 100 int get_l[120000]; 101 int found(int x){ 102 int rx = x; 103 while(pre[rx]!=rx)rx = pre[rx]; 104 while(pre[x]!=rx){ 105 int temp = pre[x]; 106 pre[x] = rx; 107 x = temp; 108 } 109 return rx; 110 } 111 void tarjan(int now,int fa){ 112 arr[now] = 1; 113 for(int i=0;i<lca[now].size();i++){ 114 if(arr[lca[now][i].dis]){ 115 get_l[lca[now][i].num] = found(lca[now][i].dis); 116 } 117 } 118 for(int i=0;i<g[now].size();i++){ 119 if(arr[g[now][i].to]) continue; 120 tarjan(g[now][i].to,now); 121 } 122 pre[found(now)] = found(fa); 123 } 124 125 void change(int l,int r,int c,int delta,int now){ 126 if(t[now].f) push_down(now); 127 if(l == c && r == c){ 128 SUM = delta; 129 MIN = delta; 130 MAX = delta; 131 return; 132 } 133 int mid = (l+r) >> 1; 134 if(c <= mid)change(l,mid,c,delta,now * 2); 135 else change(mid+1,r,c,delta,now * 2 + 1); 136 push_up(now); 137 } 138 void opp(int l,int r,int begin,int end,int now){//[l,r]树,[begin,end]询问 139 if(t[now].f) push_down(now); 140 if(begin>r||end<l||begin>end)return; 141 if(l>=begin&&r<=end){ 142 t[now].f ^=1; 143 if(t[now].f)push_down(now); 144 return; 145 } 146 int mid = (l + r) >> 1; 147 opp(l,mid,begin,end,now*2); 148 opp(mid+1,r,begin,end,now*2+1); 149 push_up(now); 150 } 151 152 struct stru{int sum,max,min;}; 153 154 stru merge(stru a,stru b){ 155 stru c = (stru){a.sum+b.sum,max(a.max,b.max),min(a.min,b.min)}; 156 return c; 157 } 158 159 stru get_sum(int l,int r,int begin,int end,int now){ 160 if(t[now].f) push_down(now); 161 if(begin > r || end < l||begin>end) return (stru){0,-INT_MAX,INT_MAX}; 162 if(l >= begin && r <= end){ 163 return (stru){SUM,MAX,MIN}; 164 } 165 int mid = (l+r) >> 1; 166 stru ans = get_sum(l,mid,begin,end,now * 2); 167 ans = merge(ans,get_sum(mid+1,r,begin,end,now*2+1)); 168 push_up(now); 169 return ans; 170 } 171 172 int main(){ 173 ios::sync_with_stdio(false); 174 int n; cin >> n; 175 edges.push_back((ed){0,0}); 176 for(int i=1;i<n;i++){ 177 int x,y,w; 178 cin >> x >> y >> w; 179 x++;y++; 180 edges.push_back((ed){x,y}); 181 g[x].push_back((edge){y,w}); 182 g[y].push_back((edge){x,w}); 183 } 184 dfs1(1,-1,1); 185 memset(arr,0,sizeof(arr)); 186 dfs2(1,1); 187 build_tree(1,bh,1); 188 int m;cin >> m; 189 for(int i=1;i<=m;i++){ 190 string str; cin >> str; 191 if(str[0] == 'C') A[i].dir = 1; 192 if(str[0] == 'N') A[i].dir = 2; 193 if(str[0] == 'S') A[i].dir = 3; 194 if(str[1] == 'A') A[i].dir = 4; 195 if(str[1] == 'I') A[i].dir = 5; 196 int u,v; cin >> u >> v; 197 if(A[i].dir!=1)u++,v++; 198 A[i].u = u; 199 A[i].v = v; 200 if(A[i].dir == 1) continue; 201 lca[u].push_back((point){v,i}); 202 lca[v].push_back((point){u,i}); 203 } 204 memset(arr,0,sizeof(arr)); 205 for(int i=1;i<=n;i++) pre[i] = i; 206 tarjan(1,-1); 207 for(int i=1;i<=m;i++){ 208 if(A[i].dir == 1){ 209 int u = edges[A[i].u].from; 210 int v = edges[A[i].u].to; 211 if(fa[v] != u) swap(u,v); 212 if(son[u] == v){ 213 int h = head[v]; 214 int bg = num[h]; 215 int ch = dep[u]-dep[h]; 216 bg = bg + ch; 217 change(1,bh,bg,A[i].v,1); 218 }else{ 219 int e = to_fa[v]; 220 int ne = fto_fa[v]; 221 g[u][ne].w = A[i].v; 222 g[v][e].w = A[i].v; 223 } 224 continue; 225 } 226 int lac = get_l[i]; 227 int s = A[i].u,t = A[i].v; 228 if(dep[s]<=dep[t])swap(s,t); 229 if(A[i].dir == 2){ 230 while(s!=lac && dep[s] > dep[lac]){ 231 int h = head[s]; 232 if(h == s){ 233 int e = to_fa[s]; 234 int ne = fto_fa[s]; 235 g[fa[s]][ne].w = -g[fa[s]][ne].w; 236 g[s][e].w = -g[s][e].w; 237 s = fa[s]; 238 continue; 239 } 240 int bg = num[h]; 241 if(dep[h] >= dep[lac]){ 242 int ch = dep[s]-dep[h]-1; 243 int end = bg + ch; 244 opp(1,bh,bg,end,1); 245 s = h; 246 }else{ 247 bg = num[lac]; 248 int ch = dep[s]-dep[lac]-1; 249 int end = bg + ch; 250 opp(1,bh,bg,end,1); 251 s = lac; 252 break; 253 } 254 } 255 while(t!=lac&&dep[t] > dep[lac]){ 256 int h = head[t]; 257 if(h == t){ 258 int e = to_fa[t]; 259 int ne = fto_fa[t]; 260 g[fa[t]][ne].w = -g[fa[t]][ne].w; 261 g[t][e].w = -g[t][e].w; 262 t = fa[t]; 263 continue; 264 } 265 int bg = num[h]; 266 if(dep[h] > dep[lac]){ 267 int ch = dep[t]-dep[h]-1; 268 int end = bg + ch; 269 opp(1,bh,bg,end,1); 270 t = h; 271 }else{ 272 bg = num[lac]; 273 int ch = dep[t]-dep[lac]-1; 274 int end = bg+ch; 275 opp(1,bh,bg,end,1); 276 break; 277 } 278 } 279 continue; 280 } 281 int &pd = A[i].dir; 282 if(pd == 3||pd == 4 ||pd == 5){ 283 int ans = 0; 284 if(pd == 5) ans = INT_MAX; 285 if(pd == 4) ans = -INT_MAX; 286 while(s!=lac&&dep[s] > dep[lac]){ 287 int h = head[s]; 288 if(h == s){ 289 int e = to_fa[s]; 290 if(pd == 3) ans += g[s][e].w; 291 else if(pd == 4) ans = max(ans,g[s][e].w); 292 else ans = min(ans,g[s][e].w); 293 s = fa[s]; 294 continue; 295 } 296 int bg = num[h]; 297 if(dep[h] >= dep[lac]){ 298 int ch = dep[s] - dep[h] - 1; 299 int end = bg + ch; 300 stru p = get_sum(1,bh,bg,end,1); 301 if(pd == 3) ans += p.sum; 302 else if(pd == 4) ans = max(ans,p.max); 303 else ans = min(ans,p.min); 304 s = h; 305 }else{ 306 bg = num[lac]; 307 int ch = dep[s] - dep[lac] - 1; 308 int end = bg + ch; 309 stru p = get_sum(1,bh,bg,end,1); 310 if(pd == 3) ans += p.sum; 311 else if(pd == 4) ans = max(ans,p.max); 312 else ans = min(ans,p.min); 313 s = lac; 314 break; 315 } 316 } 317 while(t!=lac&&dep[t] > dep[lac]){ 318 int h = head[t]; 319 if(h == t){ 320 int e = to_fa[t]; 321 if(pd == 3) ans += g[t][e].w; 322 else if(pd == 4) ans = max(ans,g[t][e].w); 323 else ans = min(ans,g[t][e].w); 324 t = fa[t]; 325 continue; 326 } 327 int bg = num[h]; 328 if(dep[h] > dep[lac]){ 329 int ch = dep[t] - dep[h] - 1; 330 int end = bg + ch; 331 stru p = get_sum(1,bh,bg,end,1); 332 if(pd == 3) ans += p.sum; 333 else if(pd == 4) ans = max(ans,p.max); 334 else ans = min(ans,p.min); 335 t = h; 336 }else{ 337 bg = num[lac]; 338 int ch = dep[t] - dep[lac] - 1; 339 int end = bg + ch; 340 stru p = get_sum(1,bh,bg,end,1); 341 if(pd == 3) ans += p.sum; 342 else if(pd == 4) ans = max(ans,p.max); 343 else ans = min(ans,p.min); 344 break; 345 } 346 } 347 printf("%d\n",ans); 348 } 349 } 350 return 0; 351 }