• 树的维护


    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

    思路{
      果断树链剖分,lazy等一系列取反操作等,思想很明确,但要注意细节,如修改时更新当前节点的值,重链端点记录等;
      yade,调了我一上午!!!
      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<queue>
      7 #include<ctime>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 #define MAXX 100010
     12 #define rs ((o<<1)|1)
     13 #define ls (o<<1)
     14 #define INF 99999999
     15 using namespace std;
     16 struct ed{int nxt,to,c;}e[MAXX*4];
     17 struct t{int ma,mi;}tree[MAXX*4];
     18 int id[MAXX],top[MAXX],siz[MAXX],hson[MAXX],fa[MAXX],deep[MAXX];
     19 int head[MAXX],w[MAXX],sum,tot,n,nw[MAXX],lazy[MAXX*4];
     20 void add(int u,int v,int c){e[tot].nxt=head[u];e[tot].to=v;e[tot].c=c;head[u]=tot++;}
     21 void ADD(int u,int v,int c){add(u,v,c),add(v,u,c);}
     22 struct ac{
     23   int fr,to;
     24 }a[MAXX];
     25 void dfs1(int u,int faa){
     26   siz[u]=1,fa[u]=faa,deep[u]=deep[faa]+1;
     27   for(int i=head[u];i!=-1;i=e[i].nxt)if(e[i].to!=faa){
     28       w[e[i].to]=e[i].c;
     29       int v=e[i].to;dfs1(v,u);siz[u]+=siz[v];
     30       if(siz[hson[u]]<siz[v])hson[u]=v;
     31     }
     32 }
     33 void dfs2(int u,int toop){
     34   top[u]=toop;id[u]=++sum;nw[sum]=w[u];
     35   if(hson[u])dfs2(hson[u],toop);
     36   for(int i=head[u];i!=-1;i=e[i].nxt)if(e[i].to!=fa[u] && e[i].to!=hson[u])dfs2(e[i].to,e[i].to);
     37 }
     38 #define tr tree
     39 void down(int o){
     40   int xx=tree[rs].ma,yy=tree[rs].mi;
     41   if(lazy[o]==1) return;
     42   tr[rs].ma=(-1)*yy;tr[rs].mi=(-1)*xx;lazy[rs]*=(-1);
     43   xx=tree[ls].ma,yy=tree[ls].mi;
     44   tr[ls].ma=(-1)*yy;tr[ls].mi=(-1)*xx;lazy[ls]*=(-1);
     45   lazy[o]=1;return;
     46 }
     47 void build(int o,int l,int r){
     48   if(l==r){
     49     if(l!=1)tree[o].ma=nw[l],tree[o].mi=nw[l];
     50     else tree[o].ma=(-1)*INF,tree[o].mi=INF;
     51     return;
     52   }
     53   int mid=(l+r)>>1;
     54   build(ls,l,mid),build(rs,mid+1,r);
     55   tree[o].ma=max(tree[rs].ma,tree[ls].ma);
     56   tree[o].mi=min(tree[rs].mi,tree[ls].mi);
     57 }
     58 void update(int o,int l,int r,int p,int v){
     59   if(r!=l)down(o);
     60   if(l==r&&r==p){tree[o].ma=v,tree[o].mi=v;return;}   
     61   int mid=(l+r)>>1;
     62   if(mid<p)update(rs,mid+1,r,p,v);
     63   else update(ls,l,mid,p,v);
     64   tree[o].ma=max(tree[rs].ma,tree[ls].ma);
     65   tree[o].mi=min(tree[rs].mi,tree[ls].mi);
     66 }
     67 void qufan(int o,int l,int r,int ll,int rr){
     68   if(l!=r)down(o);
     69   if(l>=ll&&r<=rr){
     70     lazy[o]*=-1;
     71     int xx=tree[o].ma,yy=tree[o].mi;
     72     tree[o].mi=(-1)*xx,tree[o].ma=(-1)*yy;
     73     return;
     74   }
     75   int mid=(l+r)>>1;
     76   if(mid<ll)qufan(rs,mid+1,r,ll,rr);
     77   else if(rr<=mid)qufan(ls,l,mid,ll,rr);
     78   else qufan(ls,l,mid,ll,rr),qufan(rs,mid+1,r,ll,rr);
     79     tree[o].ma=max(tree[rs].ma,tree[ls].ma);
     80   tree[o].mi=min(tree[rs].mi,tree[ls].mi);
     81 }
     82 int querymax(int o,int l,int r,int ll,int rr){
     83   if(l!=r)down(o);
     84   if(l>=ll&&r<=rr)return tree[o].ma;
     85   int mid=(l+r)>>1;
     86   if(mid<ll)return querymax(rs,mid+1,r,ll,rr);
     87   else if(rr<=mid)return querymax(ls,l,mid,ll,rr);
     88   else return max(querymax(ls,l,mid,ll,rr),querymax(rs,mid+1,r,ll,rr));
     89 }
     90 int lca_max(int x,int y){
     91   int ans=-INF;
     92   while(top[x]!=top[y]){
     93     if(deep[top[x]]<deep[top[y]])swap(x,y);
     94     ans=max(ans,querymax(1,1,n,id[top[x]],id[x]));
     95     x=fa[top[x]];
     96   }
     97   if(deep[x]>deep[y])swap(x,y);
     98   if(x==y) return ans;
     99   ans=max(ans,querymax(1,1,n,id[x]+1,id[y]));
    100   return ans;
    101 }
    102 void lca_ne(int x,int y){
    103   while(top[x]!=top[y]){
    104     if(deep[top[x]]<deep[top[y]])swap(x,y);
    105     qufan(1,1,n,id[top[x]],id[x]);
    106     x=fa[top[x]];
    107   }
    108   if(deep[x]>deep[y])swap(x,y);
    109   if(x==y)return;
    110   qufan(1,1,n,id[x]+1,id[y]);
    111 }
    112 int main(){
    113   memset(head,-1,sizeof(head));
    114   scanf("%d",&n);
    115   for(int i=1;i<=n*4*2;i++) lazy[i]=1;
    116   for(int i=1;i<n;++i){int u,v,c;scanf("%d%d%d",&u,&v,&c);ADD(u,v,c);a[i].fr=u;a[i].to=v;}
    117   string ss;dfs1(1,0),dfs2(1,1);
    118   build(1,1,n);
    119   while(1){
    120     cin>>ss;
    121     if(ss[0]=='D') break;
    122     if(ss[0]=='Q'){
    123       int u,v;
    124       scanf("%d%d",&u,&v);
    125       printf("%d
    ",lca_max(u,v));
    126     }
    127     else
    128       if(ss[0]=='C'){
    129     int x,y;scanf("%d%d",&x,&y);
    130     int fr=a[x].fr,to=a[x].to;
    131         if(deep[fr]>deep[to])swap(fr,to);
    132     update(1,1,n,id[to],y);
    133       }
    134       else {
    135     int x,y;scanf("%d%d",&x,&y);
    136     lca_ne(x,y);
    137       }
    138   }
    139   return 0;
    140 }
    }
  • 相关阅读:
    企业如何才能“勾搭”上服务网格技术?
    行云创新:云原生加速企业释放数据价值
    行云创新:后疫情时代,云原生为酒店数字化转型破局
    行云创新CEO马洪喜荣获“2021杰出质造人物奖”
    SolarMesh发布 v1.6.1版本,再不来体验就......
    什么是云原生?如何建设云原生平台?
    行云创新联合上汽乘用车打造云原生技术平台,加快实现数字化转型
    五分钟搭建你的第一个区块链应用
    mysql 存储过程
    MySQL-binlog日志格式 binlog_format三种模式详解
  • 原文地址:https://www.cnblogs.com/zzmmm/p/6632992.html
Copyright © 2020-2023  润新知