zoukankan      html  css  js  c++  java
  • POJ 3237

    题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度;取反操作,将a点和b点之间的路径权值都取相反数;变化操作,把某条边的权值变成指定的值。
      1 #include <cstdio>
      2 #include <iostream>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 #define N 10010
      7 #define ls o<<1
      8 #define rs o<<1|1
      9 #define define_m int m=(l+r)>>1
     10 const int INF = 2000000000;
     11 int first[N] , k;
     12 struct Edge{
     13     int x , y , next , w;
     14     Edge(){}
     15     Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){}
     16 }e[N<<1];
     17 
     18 void add_edge(int x ,int y , int w)
     19 {
     20     e[k] = Edge(x , y , first[x] , w);
     21     first[x] = k++;
     22 }
     23 
     24 int sz[N] , son[N] , dep[N] , fa[N] , num , id[N] , top[N];
     25 void dfs(int u , int f , int d)
     26 {
     27     sz[u] = 1 , fa[u] = f , son[u] = 0 , dep[u] = d;
     28     int maxn = 0;
     29     for(int i=first[u] ; ~i ; i=e[i].next){
     30         int v = e[i].y;
     31         if(v == f) continue;
     32         dfs(v , u , d+1);
     33         sz[u] += sz[v];
     34         if(maxn<sz[v]) maxn = sz[v] , son[u] = v;
     35     }
     36 }
     37 
     38 void dfs1(int u , int f , int head)
     39 {
     40     id[u] = ++num , top[u] = head;
     41     if(son[u]) dfs1(son[u] , u , head);
     42     for(int i=first[u] ; ~i ; i=e[i].next){
     43         int v = e[i].y;
     44         if(v == f || v==son[u]) continue;
     45         dfs1(v , u , v);
     46     }
     47 }
     48 
     49 int mx[N<<2] , mn[N<<2] , neg[N<<2] , val[N];
     50 
     51 void push_down(int o)
     52 {
     53     if(neg[o]<0){
     54         neg[ls]*=neg[o] , neg[rs]*=neg[o];
     55         int tmp;
     56         tmp = mx[ls] , mx[ls] = -mn[ls] , mn[ls] = -tmp;
     57         tmp = mx[rs] , mx[rs] = -mn[rs] , mn[rs] = -tmp;
     58         neg[o] = 1;
     59     }
     60 }
     61 
     62 void push_up(int o)
     63 {
     64     mx[o] = max(mx[ls] , mx[rs]);
     65     mn[o] = min(mn[ls] , mn[rs]);
     66 }
     67 
     68 void build(int o , int l , int r)
     69 {
     70     neg[o] = 1;
     71     if(l==r){
     72         mx[o] = mn[o] = val[l];
     73         return ;
     74     }
     75     define_m;
     76     build(ls , l , m);
     77     build(rs , m+1 , r);
     78     push_up(o);
     79 }
     80 
     81 void change(int o , int l , int r , int p , int v)
     82 {
     83     if(l==r){
     84         mx[o] = mn[o] = v;
     85         return;
     86     }
     87     push_down(o);
     88     define_m;
     89     if(m>=p) change(ls , l , m , p , v);
     90     else change(rs , m+1 , r , p , v);
     91     push_up(o);
     92 }
     93 
     94 void update(int o , int l , int r , int s , int t)
     95 {
     96     if(l>=s && r<=t){
     97         int tmp;
     98         tmp = mx[o] , mx[o] = -mn[o] , mn[o] = -tmp;
     99         neg[o] *= -1;
    100         return ;
    101     }
    102     push_down(o);
    103     define_m;
    104     if(m>=s) update(ls , l , m , s , t);
    105     if(m<t) update(rs , m+1 , r , s , t);
    106     push_up(o);
    107 }
    108 
    109 int query(int o , int l , int r , int s , int t)
    110 {
    111     if(l>=s && r<=t) return mx[o];
    112     push_down(o);
    113     define_m;
    114     int ans = -INF;
    115     if(m>=s) ans=max(ans , query(ls , l , m , s , t));
    116     if(m<t) ans=max(ans , query(rs , m+1 , r , s , t));
    117     return ans;
    118 }
    119 int n , u , v , w;
    120 char str[10];
    121 
    122 void negatePath(int u , int v)
    123 {
    124     int top1 = top[u] , top2 = top[v];
    125     while(top1!=top2)
    126     {
    127         if(dep[top1]<dep[top2]){
    128             swap(top1 , top2);
    129             swap(u , v);
    130         }
    131         update(1 , 2 , num , id[top1] , id[u]);
    132         u = fa[top1];
    133         top1 = top[u];
    134     }
    135     if(u!=v){
    136         if(dep[u]<dep[v]) swap(u , v);
    137         update(1 , 2 , num , id[son[v]] , id[u]);
    138     }
    139 }
    140 
    141 int calPath(int u , int v)
    142 {
    143     int top1 = top[u] , top2 = top[v];
    144     int ret = -INF;
    145     while(top1!=top2){
    146         if(dep[top1]<dep[top2]){
    147             swap(top1 , top2);
    148             swap(u , v);
    149         }
    150         ret = max(ret , query(1 , 2 , num , id[top1] , id[u]));
    151         u = fa[top1];
    152         top1 = top[u];
    153     }
    154     if(u!=v){
    155         if(dep[u]<dep[v]) swap(u , v);
    156         ret = max(ret , query(1 , 2 , num , id[son[v]] , id[u]));
    157     }
    158     return ret;
    159 }
    160 
    161 int main()
    162 {
    163   //  freopen("in.txt" , "r" , stdin);
    164     int T;
    165     scanf("%d" , &T);
    166     while(T--)
    167     {
    168         scanf("%d" , &n);
    169         memset(first , -1  , sizeof(first));
    170         k=0;
    171         for(int i=0 ; i<n-1 ; i++){
    172             scanf("%d%d%d" , &u ,&v , &w);
    173             add_edge(u , v , w);
    174             add_edge(v , u , w);
    175         }
    176         num = 0;
    177         dfs(1 , 0 , 1);
    178         dfs1(1 , 0 , 1);
    179         for(int i=0 ; i<n ; i++){
    180             int j=i<<1 , x=e[j].x , y=e[j].y;
    181             if(fa[x]!=y) val[id[y]] = e[j].w;
    182             else val[id[x]] = e[j].w;
    183         }
    184         build(1 , 2 , num);
    185         while(scanf("%s" , str)){
    186             if(str[0] == 'D') break;
    187             if(str[0] == 'C'){
    188                 scanf("%d%d" , &u , &v);
    189                 u--;
    190                 int x = e[u*2].x , y = e[u*2].y , pos;
    191                 if(fa[x]!=y) pos = id[y];
    192                 else pos = id[x];
    193                 change(1 , 2 , num , pos , v);
    194             }
    195             else if(str[0] == 'N'){
    196                 scanf("%d%d" , &u , &v);
    197                 negatePath(u , v);
    198             }
    199             else{
    200                 scanf("%d%d" , &u , &v);
    201                 int ret = calPath(u , v);
    202                 printf("%d
    " , ret);
    203             }
    204         }
    205     }
    206     return 0;
    207 }
  • 相关阅读:
    论球迷和程序员
    山哥,你是怎么提高设计能力的?
    一个想休息的线程:JVM到底是怎么处理锁的?怎么不让我阻塞呢?
    由“面经”引发的思考
    99%的创业公司都不值得加入
    大牛是怎么炼成的?
    RMQ问题 与众不同 尚未攻克
    YbtOj例题:二叉堆3 龙珠游戏
    离散化模板
    YbtOJ练习:广搜 3 追捕小狗
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4763960.html
Copyright © 2011-2022 走看看