码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1036--树链剖分

时间:2016-08-23 22:04:46      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

模板题。。。

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define N 30001
#define INF 2147483647
vector<int>g[N];
int i,j,k,n,m,cmax[N*4],q,csum[N*4],array[N],w[N],top[N],size[N],fa[N],son[N],deep[N],w2[N],x,y,t;
char s[10];
void dfs1(int x,int f){
    int maxn;
    fa[x]=f;deep[x]=deep[fa[x]]+1;
    for(int i=0;i<g[x].size();i++)
    if(g[x][i]!=fa[x]){
        dfs1(g[x][i],x);
        size[x]+=size[g[x][i]];
        if(size[g[x][i]]>maxn){
            maxn=size[g[x][i]];
            son[x]=g[x][i];
        }
    }
    size[x]++;
}
void dfs2(int x,int tp){
    w[x]=++m;w2[m]=x;top[x]=tp;
    if(son[x])dfs2(son[x],tp);
    for(int i=0;i<g[x].size();i++)
    if(fa[x]!=g[x][i]&&g[x][i]!=son[x])dfs2(g[x][i],g[x][i]);
}
void build(int node,int l,int r){
    if(l==r){
        cmax[node]=csum[node]=array[w2[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
    cmax[node]=max(cmax[node<<1],cmax[node<<1|1]);
    csum[node]=csum[node<<1]+csum[node<<1|1];
}
void update(int node,int l,int r,int x,int t){
    if(l==r){
        csum[node]=cmax[node]=t;
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=x)update(node<<1,l,mid,x,t);else update(node<<1|1,mid+1,r,x,t);
    cmax[node]=max(cmax[node<<1],cmax[node<<1|1]);
    csum[node]=csum[node<<1]+csum[node<<1|1];
}
int query_sum(int node,int l,int r,int L,int R){
    if(l>R||r<L)return 0;
    if(l>=L&&r<=R)return csum[node];
    int mid=(l+r)>>1;
    return query_sum(node<<1,l,mid,L,R)+query_sum(node<<1|1,mid+1,r,L,R);
}
int query_max(int node,int l,int r,int L,int R){
    if(l>R||r<L)return -INF;
    if(l>=L&&r<=R)return cmax[node];
    int mid=(l+r)>>1;
    return max(query_max(node<<1,l,mid,L,R),query_max(node<<1|1,mid+1,r,L,R));
}
int query_tree_sum(int u,int v){
    int f1=top[u],f2=top[v],ans=0;
    while(f1!=f2)
    if(deep[f1]>=deep[f2]){
        ans+=query_sum(1,1,m,w[f1],w[u]);
        u=fa[f1];
        f1=top[u];
    }else{
        ans+=query_sum(1,1,m,w[f2],w[v]);
        v=fa[f2];
        f2=top[v];
    }
    if(w[u]>w[v])ans+=query_sum(1,1,m,w[v],w[u]);else ans+=query_sum(1,1,m,w[u],w[v]);
    return ans;
}
int query_tree_max(int u,int v){
    int f1=top[u],f2=top[v],ans=-INF;
    while(f1!=f2)
    if(deep[f1]>=deep[f2]){
        ans=max(ans,query_max(1,1,m,w[f1],w[u]));
        u=fa[f1];
        f1=top[u];
    }else{
        ans=max(ans,query_max(1,1,m,w[f2],w[v]));
        v=fa[f2];
        f2=top[v];
    }
    if(w[u]>w[v])ans=max(ans,query_max(1,1,m,w[v],w[u]));else ans=max(ans,query_max(1,1,m,w[u],w[v]));
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    for(i=1;i<=n;i++)scanf("%d",&array[i]);
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,m);
    scanf("%d",&q);
    for(i=1;i<=q;i++){
        scanf("%s%d%d",s,&x,&y);
        if(s[0]==C)update(1,1,m,w[x],y);
        else if(s[1]==S)printf("%d\n",query_tree_sum(x,y));else printf("%d\n",query_tree_max(x,y));
    }
    return 0;
}
bzoj1036

 

bzoj1036--树链剖分

标签:

原文地址:http://www.cnblogs.com/gjghfd/p/5800865.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!