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 }

 

posted @ 2017-04-07 20:57  社会主义市场经济  阅读(219)  评论(0编辑  收藏  举报