zoukankan      html  css  js  c++  java
  • zjoi2008 树链剖分

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;

    struct my{
        int u,v,next;
    };

    const int maxn=100000+5;
    int cnt;
    int nil=1000000000;
    my tu[maxn];
    int n;
    int head[maxn];
    int w[maxn*4];
    int size[maxn],d[maxn],fa[maxn],woson[maxn],tpos[maxn],pre[maxn],top[maxn];
    char f[10];
    int sumv[maxn*4],maxv[maxn*4];
    int tot;

    void myinsert(int u,int v){
         tu[++tot].u=u;
         tu[tot].v=v;
         tu[tot].next=head[u];
         head[u]=tot;
    }

    int read()
    {
        int p,data=0;
        char ch=0;
        while ((ch!='-') && ch<'0' || ch>'9') ch=getchar();
        if (ch=='-')
        {
            p=-1;
            ch=getchar();
        } else p=1;
        while (ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
        return data*p;
    }

    void dfs1(int u,int f){
         size[u]=1;
         for (int i=head[u];i;i=tu[i].next){
            int v=tu[i].v;
            if(v==f) continue;
            d[v]=d[u]+1;fa[v]=u;
            dfs1(v,u);
            size[u]+=size[v];
            if(size[v]>size[woson[u]]) woson[u]=v;
         }
    }

    void dfs2(int u,int frist){
         tpos[u]=++cnt;
         pre[cnt]=u;
         top[u]=frist;
         if(woson[u]) dfs2(woson[u],frist);
         for (int i=head[u];i;i=tu[i].next){
             int v=tu[i].v;
             if(v==fa[u]||v==woson[u]) continue;
             dfs2(v,v);
         }
    }

    void pushup(int x){
         sumv[x]=sumv[x<<1]+sumv[x<<1|1];
         maxv[x]=max(maxv[x<<1],maxv[x<<1|1]);
    }

    void build(int st,int l,int r){
         if(l==r){
            sumv[st]=maxv[st]=w[pre[l]];
            return ;
         }
         int mid=(l+r)>>1;
         build(st<<1,l,mid);
         build(st<<1|1,mid+1,r);
         pushup(st);
    }

    void update(int st,int l,int r,int pos,int c){
         if(l==r){
            sumv[st]=maxv[st]=c;
            return ;
         }
         int mid=(l+r)>>1;
         if(pos<=mid) update(st<<1,l,mid,pos,c);
         else update(st<<1|1,mid+1,r,pos,c);
         pushup(st);
    }

    int querysum(int st,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return sumv[st];
        }
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid) ans+=querysum(st<<1,l,mid,L,R);
        if(R>mid) ans+=querysum(st<<1|1,mid+1,r,L,R);
        return ans;
    }

    int qsum(int u,int v){
        int ans=0;
        while(top[u]!=top[v]){
            if(d[top[u]]<d[top[v]]) swap(u,v);
            ans+=querysum(1,1,n,tpos[top[u]],tpos[u]);
            u=fa[top[u]];
        }
        if(d[u]<d[v]) swap(u,v);
        ans+=querysum(1,1,n,tpos[v],tpos[u]);
        return ans;
    }

    int querymax(int st,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return maxv[st];
        }
        int ans=-nil;
        int mid=(l+r)>>1;
        if(L<=mid) ans=max(ans,querymax(st<<1,l,mid,L,R));
        if(R>mid) ans=max(ans,querymax(st<<1|1,mid+1,r,L,R));
        return ans;
    }

    int qmax(int u,int v){
        int ans=-nil;
        while(top[u]!=top[v]){
            if(d[top[u]]<d[top[v]]) swap(u,v);
            ans=max(ans,querymax(1,1,n,tpos[top[u]],tpos[u]));
            u=fa[top[u]];
        }
        if(d[u]<d[v]) swap(u,v);
        ans=max(ans,querymax(1,1,n,tpos[v],tpos[u]));
        return ans;
    }

    int main(){
        //freopen("cout.out","w",stdout);
          n=read();
          int u,v;
          for (int i=1;i<n;i++){
            u=read();
            v=read();
            myinsert(u,v);
            myinsert(v,u);
          }
        for (int i=1;i<=n;i++) w[i]=read();
        int q;
        q=read();
        d[1]=1;fa[1]=1;
        dfs1(1,-1);
        dfs2(1,1);
        build(1,1,n);
        while(q--){
            int x,y;
            scanf("%s",f);
            x=read();
            y=read();
            if(f[1]=='H') update(1,1,n,tpos[x],y);
            if(f[1]=='M') printf("%d ",qmax(x,y));
            if(f[1]=='S') printf("%d ",qsum(x,y));
        }
    return 0;
    }

  • 相关阅读:
    Codeforces Round #217 (Div. 2)B. Berland Bingo
    走迷宫1 bnu 1054
    MFC 对话框背景图片
    用Visual C++从位图文件生成任意形状的窗口
    poj 2245 Lotto
    poj 1797 Heavy Transportation
    poj 2253 Frogger
    poj 1125 Stockbroker Grapevine
    B. Books
    【转】阻塞与非阻塞socket的优缺点
  • 原文地址:https://www.cnblogs.com/lmjer/p/8490041.html
Copyright © 2011-2022 走看看