zoukankan      html  css  js  c++  java
  • P2590 [ZJOI2008]树的统计 树链剖分

      

    题目描述

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。

    我们将以下面的形式来要求你对这棵树完成一些操作:

    I. CHANGE u t : 把结点u的权值改为t

    II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值

    III. QSUM u v: 询问从点u到点v的路径上的节点的权值和

    注意:从点u到点v的路径上的节点包括u和v本身

    输入输出格式

    输入格式:

    输入文件的第一行为一个整数n,表示节点的个数。

    接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。

    接下来一行n个整数,第i个整数wi表示节点i的权值。

    接下来1行,为一个整数q,表示操作的总数。

    接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

    输出格式:

    对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    输入输出样例

    输入样例#1: 复制
    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4
    
    输出样例#1: 复制
    4
    1
    2
    2
    10
    6
    5
    6
    5
    16


    树剖模板题
    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    #define lson l,m,pos<<1
    #define rson m+1,r,pos<<1|1
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    const int M=1e6;
    
    int t[N<<2],col[N<<2],w[N],n,mod,m,root,node[N],t2[N<<2];
    
    void up(int pos)
    {
        t[pos]=t[pos<<1]+t[pos<<1|1];
        t2[pos]=max(t2[pos<<1],t2[pos<<1|1]);
    }
    
    void build(int l,int r,int pos)
    {
        col[pos]=0;
        if(l==r){t[pos]=t2[pos]=w[l];return ;}//w为重新编号的权值
        int m=(l+r)>>1;
        build(lson);build(rson);
        up(pos);
    }
    void update(int L,int R,int x,int l,int r,int pos)
    {
        if(L<=l&&r<=R)
        {
            t[pos]=x;t2[pos]=x;return ;
        }
        //down(r-l+1,pos);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,x,lson);
        if(R>m)update(L,R,x,rson);
        up(pos);
    }
    int query(int L,int R,int l,int r,int pos)
    {
        int ans=0;
        if(L<=l&&r<=R)return t[pos];
        //down(r-l+1,pos);
        int m=(l+r)>>1;
        if(L<=m)ans+=query(L,R,lson);
        if(R>m)ans+=query(L,R,rson);
        up(pos);
        return ans;
    }
    int querymax(int L,int R,int l,int r ,int pos)
    {
        int ans=-inf;
        if(L<=l&&r<=R)return t2[pos];
        int m=(l+r)>>1;
        if(L<=m)ans=max(ans,querymax(L,R,lson));
        if(R>m)ans=max(ans,querymax(L,R,rson));
        return ans;
    }
    ///////////////////////////////
    int dep[N],siz[N],fa[N],son[N],head[M],pos,id[N],top[N],cnt;
    struct Edge
    {
        int to,nex;
    }edge[M];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        edge[pos].to=b;
        head[a]=pos;
    }
    void dfs1(int x,int f,int deep)
    {
        dep[x]=deep;
        fa[x]=f;
        siz[x]=1;
        int maxson=-1;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(v==f)continue;
            dfs1(v,x,deep+1);
            siz[x]+=siz[v];
            if(siz[v]>maxson)maxson=siz[v],son[x]=v;
        }
    }
    void dfs2(int x,int topf)
    {
        id[x]=++cnt;
        w[cnt]=node[x];
        top[x]=topf;
        if(!son[x])return;
        dfs2(son[x],topf);
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(v==fa[x]||v==son[x])continue;
            dfs2(v,v);
        }
    }
    int qrange(int x,int y)//询问x到y最短路径的权值和
    {
        int ans=0;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans+=query(id[top[x]],id[x],1,n,1);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        ans=(ans+query(id[x],id[y],1,n,1));
        return ans;
    }
    int qmax(int x,int y)
    {
        int ans=-inf;
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans=max(ans,querymax(id[top[x]],id[x],1,n,1) );
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        ans=max(ans,querymax(id[x],id[y],1,n,1));
        return ans;
    }
    
    int main()
    {
        RI(n);
        rep(i,1,n-1){int a,b;RII(a,b);add(a,b);add(b,a);}
        rep(i,1,n)RI(node[i]);
        dfs1(1,0,1);dfs2(1,1);
        build(1,n,1);
        RI(m);
        rep(i,1,m)
        {
            string s;cin>>s;int a,b;
            if(s=="QMAX"){RII(a,b);printf("%d
    ",qmax(a,b));}
            else if(s=="QSUM"){RII(a,b);printf("%d
    ",qrange(a,b));}
            else RII(a,b),update(id[a],id[a],b,1,n,1);
        }
        return 0;
    }
    View Code


  • 相关阅读:
    分页封装实用工具类及其使用方法
    Oracle
    [置顶] Android高德地图显示气泡框
    设计模式 笔记 观察者模式
    数据质量,中国希望
    谁更胜一筹:技术解析 Google App Engine 和 Amazon EC2
    GZIP Http Servlet Response
    谁更胜一筹:技术解析 Google App Engine 和 Amazon EC2
    腾讯对外发布微博开放平台 API
    GZIP Http Servlet Response
  • 原文地址:https://www.cnblogs.com/bxd123/p/11162774.html
Copyright © 2011-2022 走看看