zoukankan      html  css  js  c++  java
  • bzoj1036 [ ZJOI2008 ] --树链剖分

    模板题。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 30001
    #define INF 1000000000
    inline char Nc(){
        static char buf[100000],*p1=buf,*p2=buf;
        if(p1==p2){
            p2=(p1=buf)+fread(buf,1,100000,stdin);
            if(p1==p2)return EOF;
        }
        return *p1++;
    }
    inline void Read(int& x){
        char c=Nc(),b=1;
        for(;c<'0'||c>'9';c=Nc())if(c=='-')b=-1;
        for(x=0;c>='0'&&c<='9';x=x*10+c-48,c=Nc());x*=b;
    }
    inline void Read(char* s){
        int i=0;
        char c=Nc();
        while(c!=' ')s[i]=c,i++,c=Nc();
    }
    int Len;
    char s[20];
    inline void Print(int x){
        if(x<0){
            putchar('-');
            x=-x;
        }
        if(!x){
            putchar('0');putchar('
    ');
            return;
        }
        for(Len=0;x;x/=10)s[++Len]=x%10;
        for(;Len;Len--)putchar(s[Len]+48);
        putchar('
    ');
    }
    struct Edge{
        int To,Next;
    }e[N<<1];
    inline int _Max(int x,int y){
        return x>y?x:y;
    }
    int h[N],i,j,k,Num,n,m,T,a[N],w[N],x,y,w2[N],Top[N],Size[N],Son[N],f[N],Sum[N<<2],Max[N<<2],Deep[N];
    char S[20];
    inline void Add(int x,int y){
        e[++Num].To=y;e[Num].Next=h[x];h[x]=Num;
    }
    void Dfs1(int x,int Fa){
        f[x]=Fa;Size[x]=1;Deep[x]=Deep[Fa]+1;
        for(int i=h[x];i;i=e[i].Next)
        if(e[i].To!=Fa){
            Dfs1(e[i].To,x);
            Size[x]+=Size[e[i].To];
            if(Size[e[i].To]>Size[Son[x]])Son[x]=e[i].To;
        }
    }
    void Dfs2(int x,int Tmp){
        w[x]=++m;w2[m]=x;Top[x]=Tmp;
        if(Son[x])Dfs2(Son[x],Tmp);
        for(int i=h[x];i;i=e[i].Next)
        if(e[i].To!=f[x]&&e[i].To!=Son[x])Dfs2(e[i].To,e[i].To);
    }
    void Build(int Node,int l,int r){
        if(l==r){
            Sum[Node]=Max[Node]=a[w2[l]];
            return;
        }
        int Mid=(l+r)>>1;
        Build(Node<<1,l,Mid);
        Build(Node<<1|1,Mid+1,r);
        Sum[Node]=Sum[Node<<1]+Sum[Node<<1|1];
        Max[Node]=_Max(Max[Node<<1],Max[Node<<1|1]);
    }
    void Update(int Node,int l,int r,int x,int y){
        if(l==r){
            Sum[Node]=Max[Node]=y;
            return;
        }
        int Mid=(l+r)>>1;
        if(x<=Mid)Update(Node<<1,l,Mid,x,y);else Update(Node<<1|1,Mid+1,r,x,y);
        Sum[Node]=Sum[Node<<1]+Sum[Node<<1|1];
        Max[Node]=_Max(Max[Node<<1],Max[Node<<1|1]);
    }
    int Querysum(int Node,int l,int r,int L,int R){
        if(l>R||r<L)return 0;
        if(l>=L&&r<=R)return Sum[Node];
        int Mid=(l+r)>>1;
        return Querysum(Node<<1,l,Mid,L,R)+Querysum(Node<<1|1,Mid+1,r,L,R);
    }
    int Querymax(int Node,int l,int r,int L,int R){
        if(l>R||r<L)return -INF;
        if(l>=L&&r<=R)return Max[Node];
        int Mid=(l+r)>>1;
        return _Max(Querymax(Node<<1,l,Mid,L,R),Querymax(Node<<1|1,Mid+1,r,L,R));
    }
    int Querysum_tree(int u,int v){
        int Ans=0;
        while(Top[u]!=Top[v])
        if(Deep[Top[u]]<Deep[Top[v]]){
            Ans+=Querysum(1,1,m,w[Top[v]],w[v]);
            v=f[Top[v]];
        }else{
            Ans+=Querysum(1,1,m,w[Top[u]],w[u]);
            u=f[Top[u]];
        }
        if(w[u]<w[v])Ans+=Querysum(1,1,m,w[u],w[v]);else Ans+=Querysum(1,1,m,w[v],w[u]);
        return Ans;
    }
    int Querymax_tree(int u,int v){
        int Ans=-INF;
        while(Top[u]!=Top[v])
        if(Deep[Top[u]]<Deep[Top[v]]){
            Ans=_Max(Ans,Querymax(1,1,m,w[Top[v]],w[v]));
            v=f[Top[v]];
        }else{
            Ans=_Max(Ans,Querymax(1,1,m,w[Top[u]],w[u]));
            u=f[Top[u]];
        }
        if(w[u]<w[v])Ans=_Max(Ans,Querymax(1,1,m,w[u],w[v]));else Ans=_Max(Ans,Querymax(1,1,m,w[v],w[u]));
        return Ans;
    }
    int main()
    {
        Read(n);
        for(i=1;i<n;i++){
            Read(x);Read(y);
            Add(x,y);
            Add(y,x);
        }
        for(i=1;i<=n;i++)Read(a[i]);
        Dfs1(1,0);
        Dfs2(1,1);
        Build(1,1,m);
        Read(T);
        while(T--){
            Read(S);Read(x);Read(y);
            if(S[0]=='C')Update(1,1,m,w[x],y);else
            if(S[1]=='S')Print(Querysum_tree(x,y));else Print(Querymax_tree(x,y));
        }
        return 0;
    }
    bzoj1036
  • 相关阅读:
    VC窗口类的销毁-是否需要delete
    ScrollView在调试状态一点击就挂的原因(OnMouseActivate)
    TextOut与DrawText的区别
    NOIP2010 引水入城
    欧拉回路
    BZOJ 1202: [HNOI2005]狡猾的商人
    codevs 2491 玉蟾宫
    BZOJ 1059: [ZJOI2007]矩阵游戏
    BZOJ 1024: [SCOI2009]生日快乐
    ural 1297. Palindrome
  • 原文地址:https://www.cnblogs.com/gjghfd/p/5800865.html
Copyright © 2011-2022 走看看