zoukankan      html  css  js  c++  java
  • Qtree 1

    原题这里

    这题要用到树链剖分

    不会树剖的同学点这里

    把边权变为其dep比较深的那个点的点权,然后树剖(注意LCA的权值是不能算进去的。)

    //第一次树剖套线段树,以前都是套树状数组的。

    #include<bits/stdc++.h>
    #define sight(c) ('0'<=c&&c<='9')
    using namespace std;
    #define N 100017
    #define Mid (l+r>>1)
    #define eho(x) for(int i=head[x];i;i=net[i])
    int fall[N<<1],net[N<<1],cost[N<<1],head[N],f[N],dep[N],siz[N],son[N];
    int ma[N<<2],tot,n,co[N],id[N],tim,tp[N],ans,x,y,w,be[N],df[N];
    char ch[47];
    inline void read(int &x){
        static char c;static int b;
        for (b=1,c=getchar();!sight(c);c=getchar())if(c=='-')b=-1;
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
        x*=b;
    }
    inline void add(int x,int y,int co){
        fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=co; 
    }
    void write(int x){
        if (x<10) {putchar('0'+x); return;} write(x/10),putchar('0'+x%10);
    }
    inline void writeln(int x){
        if (x<0) putchar('-'),x*=-1;write(x); putchar('
    ');
    } 
    void dfs1(int x,int fa){//第一遍dfs
        f[x]=fa; dep[x]=dep[fa]+1; siz[x]=1;
        eho(x) if (fall[i]^fa){
            co[fall[i]]=cost[i];
            id[i>>1]=fall[i];//边所对的点
            dfs1(fall[i],x);
            siz[x]+=siz[fall[i]];
            if (siz[son[x]]<siz[fall[i]]) son[x]=fall[i];
        }
    }
    void dfs2(int x,int top) {
        be[x]=++tim;df[tim]=x; tp[x]=top;
        if (son[x]) dfs2(son[x],top);
        eho(x) if (fall[i]^f[x]&&fall[i]^son[x]) dfs2(fall[i],fall[i]);
    }
    void build(int No,int l,int r){
        if (l>=r) {
            ma[No]=co[df[l]]; return;
        }
        build(No<<1,l,Mid); build(No<<1|1,Mid+1,r);
        ma[No]=max(ma[No<<1],ma[No<<1|1]);
    }
    void change(int No,int l,int r,int t,int k){
        if (l==r) {ma[No]=k; return;}
        if (t<=Mid) change(No<<1,l,Mid,t,k);
        else change(No<<1|1,Mid+1,r,t,k);
        ma[No]=max(ma[No<<1],ma[No<<1|1]);
    }
    int query(int No,int l,int r,int L,int R){
        if (L>R) {printf("rr"); return 0;}
        if (L<=l&&r<=R) return ma[No];
        if (R<=Mid) return query(No<<1,l,Mid,L,R);
        if (L >Mid) return query(No<<1|1,Mid+1,r,L,R);
        return max(query(No<<1,l,Mid,L,Mid),query(No<<1|1,Mid+1,r,Mid+1,R));
    }
    int ask(int x,int y){//查询路径
        ans=0;
        while (tp[x]^tp[y]) {
            if (dep[tp[x]]<dep[tp[y]]) swap(x,y);
            ans=max(ans,query(1,1,n,be[tp[x]],be[x]));
            x=f[tp[x]];
        }  
        if (x^y) {//lca 不统计入答案
          if (dep[x]<dep[y]) swap(x,y);
          ans=max(ans,query(1,1,n,be[son[y]],be[x])); 
        } return ans;
    }
    int main () {
        read(n); add(0,0,0);//我们加一条不存在的边,其记号(tot)为1,那么我们的一条边在原读入中就是其tot>>1,因为我们加了2条边。
        for (int i=1;i<n;i++) {
            read(x),read(y),read(w);
            add(x,y,w); add(y,x,w);
        }
        dfs1(1,0);
        dfs2(1,1);
        build(1,1,n);
        while (scanf("%s",ch),ch[0]!='D') {
            scanf("%d %d",&x,&y);
            if (ch[0]=='C') change(1,1,n,be[id[x]],y);
            else writeln(ask(x,y));     
        }  return 0;
    }
  • 相关阅读:
    XMAPP搭建DVWA靶机
    博客滑动相册封面导航教程
    MySQL-分页与排序
    MySQL-子查询
    java方法
    JSP小结
    javaScript入门介绍2
    Codeforces Global Round 13
    第一章、OS引论1
    JavaScript入门介绍2021/02/27
  • 原文地址:https://www.cnblogs.com/rrsb/p/8287715.html
Copyright © 2011-2022 走看看