zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    348     }
    349     }
    350     return 0;
    351 }
  • 相关阅读:
    hdu 5646 DZY Loves Partition
    bzoj 1001 狼抓兔子 平面图最小割
    poj 1815 Friendship 最小割 拆点 输出字典序
    spoj 1693 Coconuts 最小割 二者取其一式
    hdu 5643 King's Game 约瑟夫环变形
    约瑟夫环问题
    hdu 5642 King's Order
    CodeForces 631C Report
    1039: C语言程序设计教程(第三版)课后习题9.4
    1043: C语言程序设计教程(第三版)课后习题10.1
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/6679969.html
Copyright © 2011-2022 走看看