zoukankan      html  css  js  c++  java
  • bzoj1036: [ZJOI2008]树的统计Count

    第一道树链剖分。。。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define adde(u,v) add(u,v) ,add(v,u)
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    #define lson l,m,x<<1
    #define rson m+1,r,x<<1|1
    int read(){
        int x=0;char c=getchar();bool f=true;
        while(!isdigit(c)) {
            if(c=='-') f=false;c=getchar();
        }
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        return f?x:-x;
    }
    const int nmax=30005;
    const int inf=0x7f7f7f7f;
    struct edge{
        int to;
        edge *next;
    };
    edge edges[nmax<<1],*pt=edges,*head[nmax];
    bool vis[nmax];
    int id[nmax],idx[nmax<<2],fa[nmax],size[nmax],son[nmax],dep[nmax],tp[nmax],w[nmax],n;
    char ch[100];
    struct node{
        int maxn,sum;
    };
    node tree[nmax<<2];
    void add(int s,int t){
        pt->to=t;pt->next=head[s];head[s]=pt++;
    }
    void dfs(int x){
        vis[x]=1;size[x]=1;
        qwq(x){
            int to=o->to;
            if(!vis[to]){
                dep[to]=dep[x]+1;fa[to]=x;dfs(to);
                size[x]+=size[to];
                if(!son[x]||size[to]>size[son[x]]) son[x]=to;
            }
        }
    }
    void Dfs(int x,int top){
        id[x]=++id[0];idx[id[0]]=x;tp[x]=top;
        if(son[x]) Dfs(son[x],top);
        qwq(x) if(!id[o->to]) Dfs(o->to,o->to);
    }
    void pushup(int x){
        node &o=tree[x];node &tl=tree[x<<1];node &tr=tree[x<<1|1];
        o.maxn=max(tl.maxn,tr.maxn);o.sum=tl.sum+tr.sum;
    }
    void build(int l,int r,int x){
        node &o=tree[x];
        if(l==r) {
            o.maxn=o.sum=w[idx[l]];return ;
        }
        int m=(l+r)>>1;build(lson);build(rson);pushup(x);
    }
    void update(int p,int add,int l,int r,int x){
        if(l==r) {
            tree[x].maxn=tree[x].sum=add;return ;
        }
        int m=(l+r)>>1;
        p<=m?update(p,add,lson):update(p,add,rson);pushup(x);
    }
    int querysum(int tl,int tr,int l,int r,int x){
        if(tl<=l&&tr>=r) return tree[x].sum;
        int m=(l+r)>>1;int ans=0;
        if(tl<=m) ans+=querysum(tl,tr,lson);
        if(tr>m) ans+=querysum(tl,tr,rson);
        return ans;
    }
    int querymax(int tl,int tr,int l,int r,int x){
        if(tl<=l&&tr>=r) return tree[x].maxn;
        int m=(l+r)>>1;int ans=-inf;
        if(tl<=m) ans=max(ans,querymax(tl,tr,lson));
        if(tr>m) ans=max(ans,querymax(tl,tr,rson));
        return ans;
    }
    int qsum(int a,int b){
        int ans=0;
        while(tp[a]!=tp[b]){
            if(dep[tp[a]]>dep[tp[b]]) swap(a,b);
            ans+=querysum(id[tp[b]],id[b],1,n,1);
            b=fa[tp[b]];
        }
        if(dep[a]>dep[b]) swap(a,b);
        ans+=querysum(id[a],id[b],1,n,1);return ans;
    }
    int qmax(int a,int b){
        int ans=-inf;
        while(tp[a]!=tp[b]){
            if(dep[tp[a]]>dep[tp[b]]) swap(a,b);
            ans=max(ans,querymax(id[tp[b]],id[b],1,n,1));
            b=fa[tp[b]];
        }
        if(dep[a]>dep[b]) swap(a,b);
        ans=max(ans,querymax(id[a],id[b],1,n,1));return ans;
    }
    void test(int l,int r,int x){
        if(l==r) printf("%d ",tree[x].maxn);
        else{
            int m=(l+r)>>1;test(lson);test(rson);
        }
    }
    int main(){
        n=read();
        rep(i,n-1) {
            int s=read(),t=read();adde(s,t);
        }
        /*rep(i,n){
            for(edge *o=head[i];o;o=o->next) printf("%d ",o->to);
            printf("
    ");
        }*/
        clr(vis,0);clr(son,0);dep[1]=0;
        clr(id,0);clr(idx,0);id[0]=0;
        dfs(1);Dfs(1,1);
        /*rep(i,n){
            printf("%d:%d %d %d %d
    ",i,fa[i],son[i],size[i],dep[i]);
        }*/
        rep(i,n) w[i]=read();
    //  rep(i,n) printf("%d ",id[i]);
        build(1,n,1);//test(1,n,1);
        int m=read();
        rep(i,m){
            scanf("%s",ch);int a=read(),b=read();
            if(ch[0]=='C') update(id[a],b,1,n,1);
            else if(ch[1]=='M') printf("%d
    ",qmax(a,b));
            else printf("%d
    ",qsum(a,b));
        }
        return 0;
    }
    

     

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 12514  Solved: 5045
    [Submit][Status][Discuss]

    Description

      一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成
    一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
    II. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

      输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有
    一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作
    的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 
    对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

    Output

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

    Sample Input

    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

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    HINT

     

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    011 处理模型数据时@ModelAttribute的使用
    动态产生DataSource------待整理
    连接池问题
    maven加载第三方jar不能加载
    010 处理模型数据(ModelAndView,Map Model,@SessionAttributes)
    009 使用servlet API作为参数
    008 使用POJO对象绑定请求参数
    007 @CookieValue绑定请求中的cookie
    006 请求处理方法签名
    005 RequestMapping_HiddenHttpMethodFilter 过滤器
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5657466.html
Copyright © 2011-2022 走看看