zoukankan      html  css  js  c++  java
  • poj3237 Tree

    树链剖分基本操作:

    1. 修改第i条边的权值。

    2. 对树上一条路径的权值取反(正变负,负变正)。

    3. 查询树上一条路径的权值的最大值。

    因为要取反,所以要同时维护最大值和最小值。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lson l,mid,rt<<1
      5 #define rson mid+1,r,rt<<1|1
      6 using namespace std;
      7 
      8 const int N=1e4+10;
      9 const int M=2e4+10;
     10 const int inf=0x3f3f3f3f;
     11 
     12 int head[N],to[M],nxt[M],w[M],kk[M];//kk:边的编号 
     13 int tot;
     14 int dep[N],fa[N],siz[N],son[N],idx[N];//idx:每个点与它的父亲之间的边的编号 
     15 int top[N],id[N],wt[N];
     16 int cnt;
     17 int mx[N<<2],mi[N<<2],tag[N<<2];
     18 int num[N];//第x条边(按输入顺序)的新编号 
     19 int n;
     20 
     21 inline void add(int u,int v,int x,int i){
     22     to[++tot]=v,nxt[tot]=head[u],w[tot]=x,kk[tot]=i,head[u]=tot;
     23 }
     24 
     25 void dfs1(int u,int f){
     26     dep[u]=dep[f]+1;
     27     fa[u]=f;
     28     siz[u]=1;
     29     int maxs=-1;
     30     for(int i=head[u];i;i=nxt[i]){
     31         int v=to[i];
     32         if(v==f) continue;
     33         dfs1(v,u);
     34         siz[u]+=siz[v];
     35         idx[v]=i;
     36         if(siz[v]>maxs) maxs=siz[v],son[u]=v;
     37     }
     38 }
     39 
     40 void dfs2(int u,int topf){
     41     id[u]=++cnt;
     42     wt[cnt]=w[idx[u]];
     43     top[u]=topf;
     44     num[kk[idx[u]]]=cnt;
     45     if(!son[u]) return;
     46     dfs2(son[u],topf);
     47     for(int i=head[u];i;i=nxt[i]){
     48         int v=to[i];
     49         if(v==fa[u]||v==son[u]) continue;
     50         dfs2(v,v);
     51     }
     52 }
     53 
     54 inline void push_up(int rt){
     55     mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
     56     mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
     57 }
     58 
     59 inline void push_down(int rt){
     60     if(tag[rt]){
     61         int tmp=mx[rt<<1];
     62         mx[rt<<1]=-mi[rt<<1];
     63         mi[rt<<1]=-tmp;
     64         tmp=mx[rt<<1|1];
     65         mx[rt<<1|1]=-mi[rt<<1|1];
     66         mi[rt<<1|1]=-tmp;
     67         tag[rt<<1]^=1; tag[rt<<1|1]^=1;
     68         tag[rt]=0;
     69     }
     70 }
     71 
     72 void build(int l,int r,int rt){
     73     tag[rt]=0;
     74     if(l==r){
     75         mx[rt]=mi[rt]=wt[l];
     76         return;
     77     }
     78     int mid=(l+r)>>1;
     79     build(lson),build(rson);
     80     push_up(rt);
     81 }
     82 
     83 void update1(int x,int z,int l,int r,int rt){
     84     if(l==r){
     85         mx[rt]=mi[rt]=z;
     86         return;
     87     }
     88     push_down(rt);
     89     int mid=(l+r)>>1;
     90     if(x<=mid) update1(x,z,lson);
     91     if(x>mid) update1(x,z,rson);
     92     push_up(rt);
     93 }
     94 
     95 void update2(int x,int y,int l,int r,int rt){
     96     if(x<=l&&y>=r){
     97         int tmp=mx[rt];
     98         mx[rt]=-mi[rt];
     99         mi[rt]=-tmp;
    100         tag[rt]^=1;
    101         return;
    102     }
    103     push_down(rt);
    104     int mid=(l+r)>>1;
    105     if(x<=mid) update2(x,y,lson);
    106     if(y>mid) update2(x,y,rson);
    107     push_up(rt);
    108 }
    109 
    110 int query(int x,int y,int l,int r,int rt){
    111     if(x<=l&&y>=r) return mx[rt];
    112     push_down(rt);
    113     int ans=-inf;
    114     int mid=(l+r)>>1;
    115     if(x<=mid) ans=max(ans,query(x,y,lson));
    116     if(y>mid) ans=max(ans,query(x,y,rson));
    117     return ans;
    118 }
    119 
    120 inline void uprange1(int x,int z){
    121     update1(num[x],z,1,n,1);
    122 }
    123 
    124 void uprange2(int x,int y){
    125     while(top[x]!=top[y]){
    126         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    127         update2(id[top[x]],id[x],1,n,1);
    128         x=fa[top[x]];
    129     }
    130     if(x==y) return;
    131     if(dep[x]>dep[y]) swap(x,y);
    132     update2(id[x]+1,id[y],1,n,1);
    133 }
    134 
    135 int qrange(int x,int y){
    136     int ans=-inf;
    137     while(top[x]!=top[y]){
    138         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    139         ans=max(ans,query(id[top[x]],id[x],1,n,1));
    140         x=fa[top[x]];
    141     }
    142     if(x==y) return ans;
    143     if(dep[x]>dep[y]) swap(x,y);
    144     return max(ans,query(id[x]+1,id[y],1,n,1));
    145 }
    146 
    147 void init(){
    148     tot=cnt=0;
    149     memset(head,0,sizeof(head));
    150     memset(son,0,sizeof(son));
    151 }
    152 
    153 int main()
    154 {
    155     int T;
    156     char ch[10];
    157     scanf("%d",&T);
    158     while(T--){
    159         init();
    160         scanf("%d",&n);
    161         for(int i=1;i<n;i++){
    162             int u,v,x;
    163             scanf("%d%d%d",&u,&v,&x);
    164             add(u,v,x,i);
    165             add(v,u,x,i);
    166         }
    167         dfs1(1,0); dfs2(1,1);
    168         build(1,n,1);
    169         while(~scanf("%s",ch)){
    170             if(ch[0]=='D') break;
    171             if(ch[0]=='C'){
    172                 int x,z;
    173                 scanf("%d%d",&x,&z);
    174                 uprange1(x,z);
    175             }
    176             else if(ch[0]=='N'){
    177                 int x,y;
    178                 scanf("%d%d",&x,&y);
    179                 uprange2(x,y);
    180             }
    181             else{
    182                 int x,y;
    183                 scanf("%d%d",&x,&y);
    184                 printf("%d
    ",qrange(x,y));
    185             }
    186         }
    187     }
    188     return 0;
    189 }
  • 相关阅读:
    网络常用的linux系统调用
    如何在Linux下写无线网卡的驱动【转】
    理解 Linux 配置文件【转】
    每天一个linux命令【转】
    宏定义编写技巧__调试技巧【原创】
    linux 高级字符设备驱动 ioctl操作介绍 例程分析实现【转】
    Linux驱动总结3- unlocked_ioctl和堵塞(waitqueue)读写函数的实现 【转】
    初识CPU卡、SAM卡/CPU卡简介、SAM卡简介 【转】
    android中跨进程通讯的4种方式
    MISC混杂设备 struct miscdevice /misc_register()/misc_deregister()【转】
  • 原文地址:https://www.cnblogs.com/--HY--/p/13511474.html
Copyright © 2011-2022 走看看