• 「POJ3237」Tree(树链剖分)


    题意

    给棵n个点的树。边有边权然后有三种操作

    1、CHANGE i v 将编号为i的边权变为v

    2、NEGATE a b 将a到b的所有边权变为相反数。

    3、QUERY a b 查询a b路径的最大边权。

    (n,q<=10000)

    题解

    树剖裸题。

    边权下放。线段树记录最大值最小值即可。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 const int N=10010;
      8 int cnt,head[N];
      9 int size[N],fa[N],dep[N],ww[N],son[N],ide[N];
     10 int top[N],id[N],tot,w[N];
     11 int t,n;
     12 char s[100]; 
     13 struct edge{
     14     int to,nxt,w,id;
     15 }e[N*3];
     16 void add(int u,int v,int w,int id){
     17     cnt++;
     18     e[cnt].nxt=head[u];
     19     e[cnt].to=v;
     20     e[cnt].w=w;
     21     e[cnt].id=id;
     22     head[u]=cnt;
     23 }
     24 struct tree{
     25     int l,r,maxx,minn,lazy;
     26 }tr[N*8];
     27 void update(int now){
     28     tr[now].maxx=max(tr[now*2].maxx,tr[now*2+1].maxx);
     29     tr[now].minn=min(tr[now*2].minn,tr[now*2+1].minn);
     30 }
     31 void pushdown(int now){
     32     if(tr[now].lazy==0)return;
     33     int hh=tr[now*2].maxx;
     34     tr[now*2].maxx=-tr[now*2].minn;
     35     tr[now*2].minn=-hh;
     36     hh=tr[now*2+1].maxx;
     37     tr[now*2+1].maxx=-tr[now*2+1].minn;
     38     tr[now*2+1].minn=-hh;
     39     tr[now*2].lazy^=1;
     40     tr[now*2+1].lazy^=1;
     41     tr[now].lazy=0;
     42 }
     43 void dfs1(int u,int f,int deep){
     44     size[u]=1;
     45     fa[u]=f;
     46     dep[u]=deep;
     47     int maxson=-1;
     48     for(int i=head[u];i;i=e[i].nxt){
     49         int v=e[i].to;
     50         if(v==f)continue;
     51         ww[v]=e[i].w;
     52         ide[e[i].id]=v;
     53         dfs1(v,u,deep+1);
     54         size[u]+=size[v];
     55         if(size[v]>maxson){
     56             son[u]=v;
     57             maxson=size[v];
     58         }
     59     }
     60 }
     61 void dfs2(int u,int tp){
     62     top[u]=tp;
     63     id[u]=++tot;
     64     w[tot]=ww[u];
     65     if(!son[u])return;
     66     dfs2(son[u],tp);
     67     for(int i=head[u];i;i=e[i].nxt){
     68         int v=e[i].to;
     69         if(v==fa[u]||v==son[u])continue;
     70         dfs2(v,v);
     71     }
     72 } 
     73 void build(int l,int r,int now){
     74     tr[now].l=l;tr[now].r=r;
     75     tr[now].maxx=tr[now].lazy=tr[now].minn=0;
     76     if(l==r){
     77         tr[now].maxx=tr[now].minn=w[l];
     78         return;
     79     }
     80     int mid=(l+r)>>1;
     81     build(l,mid,now*2);
     82     build(mid+1,r,now*2+1);
     83     update(now);
     84 }
     85 int getmax(int l,int r,int now){
     86     pushdown(now); 
     87     if(tr[now].l==l&&tr[now].r==r){
     88         return tr[now].maxx;
     89     }
     90     int mid=(tr[now].l+tr[now].r)>>1;
     91     if(l>mid)return getmax(l,r,now*2+1);
     92     else if(r<=mid)return getmax(l,r,now*2);
     93     else {
     94         return max(getmax(l,mid,now*2),getmax(mid+1,r,now*2+1));
     95     }
     96 }
     97 void change(int x,int y,int now){
     98     pushdown(now);
     99     if(tr[now].l==tr[now].r){
    100         tr[now].maxx=tr[now].minn=y;
    101         return;
    102     }
    103     int mid=(tr[now].l+tr[now].r)>>1;
    104     if(x>mid)change(x,y,now*2+1);
    105     else if(x<=mid)change(x,y,now*2);
    106     update(now); 
    107 }
    108 void getfan(int l,int r,int now){
    109     pushdown(now);
    110     if(tr[now].l==l&&tr[now].r==r){
    111         tr[now].lazy^=1;
    112         int hh=tr[now].maxx;
    113         tr[now].maxx=-tr[now].minn;
    114         tr[now].minn=-hh;
    115         return;
    116     }
    117     int mid=(tr[now].l+tr[now].r)>>1;
    118     if(l>mid)getfan(l,r,now*2+1);
    119     else if(r<=mid)getfan(l,r,now*2);
    120     else{
    121         getfan(l,mid,now*2);
    122         getfan(mid+1,r,now*2+1); 
    123     } 
    124     update(now);
    125 }
    126 int getlca(int x,int y){
    127     while(top[x]!=top[y]){
    128         if(dep[top[x]]<dep[top[y]])swap(x,y);
    129         x=fa[top[x]];
    130     }
    131     if(dep[x]<dep[y])return x;
    132     else return y;
    133 }
    134 int getmaxl(int x,int y){
    135     int ans=-1999999999;
    136     while(top[x]!=top[y]){
    137         if(dep[top[x]]<dep[top[y]])swap(x,y);
    138         ans=max(ans,getmax(id[top[x]],id[x],1));
    139         x=fa[top[x]];
    140     }
    141     if(x==y)return ans;
    142     if(dep[x]>dep[y])swap(x,y);
    143     ans=max(ans,getmax(id[x]+1,id[y],1));
    144     return ans;
    145 }
    146 void getfanl(int x,int y){
    147     while(top[x]!=top[y]){
    148         if(dep[top[x]]<dep[top[y]])swap(x,y);
    149         getfan(id[top[x]],id[x],1);
    150         x=fa[top[x]];
    151     }
    152     if(x==y)return;
    153     if(dep[x]>dep[y])swap(x,y);
    154     getfan(id[x]+1,id[y],1);
    155 }
    156 int main(){
    157     scanf("%d",&t);
    158     for(int z=1;z<=t;z++){
    159         scanf("%d",&n);
    160         memset(head,0,sizeof(head));
    161         memset(son,0,sizeof(son));
    162         memset(dep,0,sizeof(dep));
    163         memset(fa,0,sizeof(fa));
    164         memset(size,0,sizeof(size));
    165         memset(ide,0,sizeof(ide));
    166         memset(w,0,sizeof(w));
    167         memset(ww,0,sizeof(ww));
    168         memset(id,0,sizeof(id));
    169         memset(top,0,sizeof(top));
    170         tot=0;
    171         cnt=0;
    172         for(int i=1;i<=n-1;i++){
    173             int u,v,w;
    174             scanf("%d%d%d",&u,&v,&w);
    175             add(u,v,w,i);
    176             add(v,u,w,i);
    177         }
    178         dfs1(1,0,1);
    179         dfs2(1,1);    
    180         build(1,n,1);
    181         while(scanf("%s",&s)!=EOF){
    182             if(s[0]=='D')break;
    183             if(s[0]=='Q'){
    184                 int x,y;
    185                 scanf("%d%d",&x,&y);
    186                 int LCA=getlca(x,y);
    187                 printf("%d
    ",max(getmaxl(LCA,x),getmaxl(LCA,y)));
    188             }
    189             else if(s[0]=='C'){
    190                 int x,y;
    191                 scanf("%d%d",&x,&y);
    192                 change(id[ide[x]],y,1);
    193             }
    194             else if(s[0]=='N'){
    195                 int x,y;
    196                 scanf("%d%d",&x,&y);
    197                 int LCA=getlca(x,y);
    198                 getfanl(LCA,x);
    199                 getfanl(LCA,y);
    200             }
    201         }
    202     }
    203     return 0;
    204 }
  • 相关阅读:
    ubuntu16.04编译安装PHP7.0.9,Nginx1.10,Phalcon3.1扩展
    阿里云云大使推广产品集合
    mysql性能优化-慢查询分析、优化索引和配置
    Js学习笔记(二)
    Javascript学习笔记(一)
    HashMap
    JDK 1.8 新特性
    Java转型
    Java IO
    Java正则表达式
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9450185.html
Copyright © 2020-2023  润新知