zoukankan      html  css  js  c++  java
  • POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237)

    题目大意

      给定一颗树,有边权。

      要求支持三种操作:

        操作一:更改某条边的权值。

        操作二:将某条路径上的边权取反。

        操作三:询问某条路径上的最大权值。

    解题分析

      树链剖分+线段树。练手题。

    参考程序

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 #define V 100008
      8 #define E 200008
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define INF 2000000000
     12 
     13 int cnt,n;
     14 int size[V],dep[V],fa[V],son[V],top[V],w[V],rk[V],a[V];
     15 
     16 struct line{
     17     int u,v,w,nt;
     18 }eg[E];
     19 int lt[V],sum;
     20 
     21 void adt(int u,int v,int w){
     22     eg[++sum].u=u; eg[sum].v=v; eg[sum].w=w; eg[sum].nt=lt[u]; lt[u]=sum;
     23 }
     24 void add(int u,int v,int w){
     25     adt(u,v,w); adt(v,u,w);
     26 }
     27 
     28 struct segment_tree{
     29     // 单点修改 区间取反 区间询问
     30     int mx[V<<2],mn[V<<2],lazy[V<<2];
     31     void pushup(int rt){
     32         mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
     33         mn[rt]=min(mn[rt<<1],mn[rt<<1|1]);
     34     }
     35     void pushdown(int rt){
     36         if (lazy[rt]){
     37             lazy[rt<<1]^=1;
     38             lazy[rt<<1|1]^=1;    
     39             int t=mx[rt<<1];
     40             mx[rt<<1]=-mn[rt<<1];
     41             mn[rt<<1]=-t;
     42             t=mx[rt<<1|1];
     43             mx[rt<<1|1]=-mn[rt<<1|1];
     44             mn[rt<<1|1]=-t;
     45             lazy[rt]=0;
     46         }
     47     }
     48     void build(int l,int r,int rt){
     49         lazy[rt]=0; 
     50         if (l==r){
     51             mn[rt]=mx[rt]=a[rk[l]];
     52             return;
     53         }
     54         int m=(l+r)/2;
     55         build(lson);
     56         build(rson);
     57         pushup(rt);
     58     }
     59     void update_1(int x,int val,int l,int r,int rt){
     60         if (l==r){
     61             mx[rt]=val;
     62             mn[rt]=val;
     63             return;
     64         }
     65         pushdown(rt);
     66         int m=(l+r)/2;
     67         if (x <= m) update_1(x,val,lson);
     68         if (m <  x) update_1(x,val,rson); 
     69         pushup(rt);
     70     }
     71     void  update_2(int L,int R,int l,int r,int rt){
     72         if (L<=l && r<=R){    
     73             int t=mx[rt];
     74             mx[rt]=-mn[rt];
     75             mn[rt]=-t;
     76             lazy[rt]^=1;
     77             return;
     78         }
     79         pushdown(rt);
     80         int m=(l+r)/2;
     81         if (L <= m) update_2(L,R,lson);
     82         if (m <  R) update_2(L,R,rson); 
     83         pushup(rt);
     84     }
     85     int query(int L,int R,int l,int r,int rt){
     86         if (L<=l && r<=R){
     87             return mx[rt];
     88         }
     89         pushdown(rt);
     90         int m=(l+r)/2;
     91         int res=-INF;
     92         if (L <= m) res=max(res,query(L,R,lson));
     93         if (m <  R) res=max(res,query(L,R,rson));  
     94         return res;
     95     }
     96 }T;
     97 
     98 void dfs_1(int u){
     99     dep[u]=dep[fa[u]]+1; size[u]=1; son[u]=0;
    100     for (int i=lt[u];i;i=eg[i].nt){
    101         int v=eg[i].v;
    102         if (v==fa[u]) continue;
    103         a[v]=eg[i].w;
    104         fa[v]=u;
    105         dfs_1(v);
    106         size[u]+=size[v];
    107         if (size[v]>size[son[u]]) son[u]=v;
    108     }
    109 }
    110 void dfs_2(int u,int tp){ 
    111     top[u]=tp; w[u]=++cnt; rk[cnt]=u;
    112     if (son[u]) dfs_2(son[u],tp);
    113     for (int i=lt[u];i;i=eg[i].nt){
    114         int v=eg[i].v;
    115         if (v==fa[u] || v==son[u]) continue;
    116         dfs_2(v,v);
    117     }
    118 }
    119 void find_1(int x,int y){
    120     int res=-INF;
    121     while (top[x]!=top[y]){
    122         if (dep[top[x]]<dep[top[y]]) swap(x,y);
    123         res=max(res,T.query(w[top[x]],w[x],1,n,1));
    124         x=fa[top[x]];
    125     }
    126     if (dep[x]>dep[y]) swap(x,y);
    127     res=max(res,T.query(w[x]+1,w[y],1,n,1));
    128     printf("%d
    ",res);
    129 }
    130 void find_2(int x,int y){
    131     while (top[x]!=top[y]){
    132         if (dep[top[x]]<dep[top[y]]) swap(x,y);
    133         T.update_2(w[top[x]],w[x],1,n,1);
    134         x=fa[top[x]];
    135     }
    136     if (dep[x]>dep[y]) swap(x,y);
    137     T.update_2(w[x]+1,w[y],1,n,1);
    138 }
    139 
    140 int main(){
    141     int tt;
    142     scanf("%d",&tt);
    143     while (tt--){
    144         sum=1; cnt=0;
    145         memset(lt,0,sizeof(lt));
    146         scanf("%d",&n);
    147         for (int i=1;i<n;i++){
    148             int u,v,w;
    149             scanf("%d %d %d",&u,&v,&w);
    150             add(u,v,w);
    151         }    
    152         scanf("
    ");
    153         dfs_1(1);
    154         dfs_2(1,1);
    155         T.build(1,n,1);
    156         char s[10];
    157         for (scanf("%s",s);strcmp(s,"DONE")!=0;scanf("%s",s)){    
    158             int x,y;
    159             scanf("%d %d
    ",&x,&y);
    160             if (strcmp(s,"QUERY")==0){
    161                 find_1(x,y);
    162             }
    163             if (strcmp(s,"CHANGE")==0){
    164                 int u=eg[x*2].u , v=eg[x*2].v;
    165                 if (dep[u]<dep[v]) T.update_1(w[v],y,1,n,1);
    166                     else T.update_1(w[u],y,1,n,1);
    167             }
    168             if (strcmp(s,"NEGATE")==0){
    169                 find_2(x,y);
    170             }
    171         }    
    172     }
    173 }
    View Code
  • 相关阅读:
    NOIP2020 游记
    李超线段树
    选举「elections」
    Alt+数字输入
    素数
    CSP-S2020 爆炸记
    [CF487C] Prefix Product Sequence
    [CF489E] Hiking
    L2-019 悄悄关注 (25 分)
    L2-032 彩虹瓶 (25 分)
  • 原文地址:https://www.cnblogs.com/rpSebastian/p/5730905.html
Copyright © 2011-2022 走看看