zoukankan      html  css  js  c++  java
  • POJ3237 树的维护

    P1424 - [POJ3237]树的维护

    Description

    给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一:
    CHANGE i v:将第i条边的权值改成v。
    NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。
    QUERY a b:找出点a到点b路径上各边的最大权值。

    Input

    第一行有一个整数N(N<=10000)。
    接下来N-1行每行有三个整数a,b,c,代表点a和点b之间有一条权值为c的边。这些边按照其编号从小到大给出。
    接下来是若干条指令(不超过10^5条),都按照上面所说的格式。
    最后一行是"DONE".

    Output

    对每个“QUERY”指令,输出一行,即路径上各边的最大权值。

    Sample Input

    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE

    Sample Output

    1
    3

    Hint

    Source

    POJ 3237 Tree
    树链剖分, 动态树, LCA

    线段树,TMD调了我一个晚上+半个上午,最后才知道是因为lazy标记没有下放,woc

      1 #define ls o*2
      2 #define rs o*2+1
      3 
      4 #define inf 1999999999
      5 #include<algorithm>
      6 #include<iostream>
      7 #include<iomanip>
      8 #include<cstring>
      9 #include<cstdlib>
     10 #include<cstdio>
     11 #include<queue>
     12 #include<ctime>
     13 #include<cmath>
     14 #include<stack>
     15 #include<map>
     16 #include<set>
     17 using namespace std;
     18 const int N=10010,M=N-1;
     19 struct E{
     20     int to,net,w;
     21     int fr;
     22 }e[M*2];
     23 struct TREE{
     24     int bj,Max,Min;
     25     TREE(){
     26     bj=1;
     27     }
     28 }tr[N*4];
     29 int head[N],n,num_e;
     30 void add(int x,int y,int w) {
     31     e[++num_e].to=y;e[num_e].net=head[x];head[x]=num_e;e[num_e].w=w;e[num_e].fr=x;
     32 }
     33 void down(int);
     34 int dep[N],top[N],son[N],tid[N],pos[N],fa[N],siz[N],val[N],idx;
     35 int W[N],len[N*4];
     36 int B[M*2];
     37 void dfs1(int x,int fu) {
     38     siz[x]=1;
     39     dep[x]=dep[fu]+1;//
     40     son[x]=0;
     41     fa[x]=fu;//  meinong
     42     for(int i=head[x];i;i=e[i].net) {
     43     int to=e[i].to;
     44         if(to!=fu) {
     45         val[to]=e[i].w;
     46         dfs1(to,x);
     47         siz[x] += siz[to];//  这一步竟然忘了!!!! 
     48         if(siz[to]>siz[son[x]]) son[x]=to;
     49 //        printf("x=%d son=%d",x,son[x]);P
     50         }
     51     }
     52 }
     53 void dfs2(int x,int tp) {
     54     tid[x]=++idx;
     55     pos[idx]=x;
     56     top[x]=tp;
     57     W[idx]=val[x];//
     58     if(son[x]==0) return;
     59     dfs2(son[x],tp);
     60     for(int i=head[x];i;i=e[i].net)
     61     if(e[i].to!=son[x]&&dep[e[i].to]>dep[x]) {
     62         dfs2(e[i].to,e[i].to);
     63     }
     64 }
     65 void build(int o,int L,int R) {
     66     if(L==R) {
     67     if(L==1) tr[o].Max=-inf,tr[o].Min=inf;
     68      else 
     69       tr[o].Max=W[L],tr[o].Min=W[L];
     70     return;
     71     }
     72     int mid=(L+R)>>1;
     73     build(ls,L,mid);
     74     build(rs,mid+1,R);
     75     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
     76     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
     77 }
     78 void Update(int o,int L,int R,int p,int x) {
     79     if(L!=R) down(o);
     80     if(p==L&&R==p) {
     81     tr[o].Max=x;tr[o].Min=x;
     82     return;
     83     }
     84     int mid=(L+R)>>1;
     85     if(p<=mid) Update(ls,L,mid,p,x);
     86     else Update(rs,mid+1,R,p,x);
     87     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
     88     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
     89 }
     90 void GG(int,int,int,int,int);
     91 //  GG Update()
     92 void solveG(int x,int y) {
     93     while(top[x]!=top[y]) {
     94         if(dep[top[x]]>dep[top[y]]) swap(x,y);
     95         GG(1,1,n,tid[top[y]],tid[y]);
     96         y=fa[top[y]];
     97     }
     98     if(dep[x]>dep[y]) swap(x,y);
     99     if(x==y) return;//  y
    100     GG(1,1,n,tid[x]+1,tid[y]);
    101 }
    102 void down(int o) {
    103     int mi;
    104     int k=tr[o].bj;
    105     if(tr[o].bj==1) return;
    106     mi=tr[ls].Min;tr[ls].Min=k*tr[ls].Max,tr[ls].Max=mi*k;//mi
    107     mi=tr[rs].Min;tr[rs].Min=k*tr[rs].Max,tr[rs].Max=k*mi;
    108     tr[o].bj=1;//复原 //  tr[o].bj==1
    109     tr[ls].bj*=-1;
    110     tr[rs].bj*=-1;//
    111     return;
    112 }
    113 int querymax(int o,int L,int R,int l,int r) {
    114     if(L!=R) down(o);
    115     if(l<=L&&R<=r) {
    116     return tr[o].Max;
    117     }
    118     int Max=-inf;
    119     int mid=(L+R)>>1;
    120     if(l<=mid) Max=max(Max,querymax(ls,L,mid,l,r));
    121     if(r>mid) Max=max(Max,querymax(rs,mid+1,R,l,r));
    122     return Max;
    123 }
    124 
    125 void GG(int o,int L,int R,int l,int r) {
    126     if(L!=R) down(o);
    127     if(l<=L&&R<=r) {
    128         int mi=tr[o].Min,ma=tr[o].Max;
    129         //    tr[o].bj*=-1;
    130         tr[o].bj=-1;
    131         tr[o].Min=-ma;tr[o].Max=-mi;
    132         return;
    133     }
    134     int mid=(L+R)>>1;
    135     if(l<=mid) GG(ls,L,mid,l,r);
    136     if(r>mid) GG(rs,mid+1,R,l,r);
    137     tr[o].Max=max(tr[ls].Max,tr[rs].Max);
    138     tr[o].Min=min(tr[ls].Min,tr[rs].Min);
    139 }
    140 int solvemax(int x,int y) {
    141     int Max=-inf;
    142     
    143     while(top[x]!=top[y]) {
    144     if(dep[top[x]]>dep[top[y]]) swap(x,y);
    145     Max=max(Max,querymax(1,1,n,tid[top[y]],tid[y]));
    146         y=fa[top[y]];
    147     }
    148     if(dep[x]>dep[y]) swap(x,y);
    149     if(x==y) return Max;
    150     Max=max(Max,querymax(1,1,n,tid[x]+1,tid[y]));
    151     return Max;
    152 }
    153 int main() {        
    154 
    155     cin>>n;int i;
    156     for(i=1;i<n;i++) {
    157         int x,y,w;scanf("%d%d%d",&x,&y,&w);
    158         add(x,y,w);
    159         B[i]=num_e;
    160         add(y,x,w);
    161         }
    162         dfs1(1,0);
    163         dfs2(1,1);
    164         for(i=1;i<n;i++) {
    165              int x=e[B[i]].fr,y=e[B[i]].to;
    166              if(dep[x]<dep[y]) B[i]=y;
    167              else B[i]=x;
    168         }
    169         build(1,1,n);
    170         string s;
    171         while(1) {
    172         cin>>s;
    173         int a,b;scanf("%d%d",&a,&b);
    174         if(s[0]=='D') break;
    175         else if(s[0]=='C') {
    176             a=B[a];
    177             Update(1,1,n,tid[a],b);
    178         }
    179         else if(s[0]=='N') {
    180             solveG(a,b);
    181            }    
    182         else printf("%d
    ",solvemax(a,b));
    183     }
    184     return 0;
    185 }
    View Code
    我想要的 我自然会认真.
  • 相关阅读:
    图片轮播插件比较(jquerySlide与superSlide)
    footer贴底的纯css实现方法
    input line-height 兼容解决方案
    HBuilder js 自定义代码块
    HBuilder HTML 自定义代码块
    HBuilder CSS 自定义代码块
    Element-ui el-cascader不触发prop?
    css水平垂直居中
    本地存储时注意的问题
    银行卡号,每四位添加空格
  • 原文地址:https://www.cnblogs.com/ypz999/p/6621860.html
Copyright © 2011-2022 走看看