zoukankan      html  css  js  c++  java
  • [bzoj] 1036 Count

    原题

    树链剖分板子题

    树剖详解:

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    #define N 30010
    using namespace std;
    int n,x,y,m,a[N],f[N],dfn[N],deep[N],head[N],cnt=1,tp[N],ref[N],t,son[N],size[N];
    char s[10];
    struct hhh
    {
        int to,next;
    }edge[2*N];
    struct node
    {
        int l,r,data,mx;
    }tre[4*N];
    
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
        if (j=='-') fu=-1,j=getchar();
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
    
    void add(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void dfs1(int x,int fa,int dep)
    {
        f[x]=fa;
        deep[x]=dep+1;
        int mx=0;
        for (int i=head[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (v!=fa)
    	{
    	    dfs1(v,x,dep+1);
    	    size[x]+=size[v];
    	    if (size[v]>mx) son[x]=v,mx=size[v];
    	}
        }
        size[x]++;
    }
    
    void dfs2(int x,int top)
    {
        dfn[x]=++t;
        ref[t]=x;
        tp[x]=top;
        if (son[x]) dfs2(son[x],top);
        for (int i=head[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (v!=son[x] && v!=f[x])
    	    dfs2(v,v);
        }
    }
    
    void build(int i,int l,int r)
    {
        tre[i].l=l;
        tre[i].r=r;
        if (l==r)
        {
    	tre[i].data=a[ref[l]];
    	tre[i].mx=a[ref[l]];
    	return ;
        }
        int mid=(l+r)>>1;
        build(i*2,l,mid);
        build(i*2+1,mid+1,r);
        tre[i].data=tre[i*2].data+tre[i*2+1].data;
        tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
    }
    
    void modify(int i,int x,int y)
    {
        if (tre[i].l==x && tre[i].l==tre[i].r)
        {
    	tre[i].data=y;
    	tre[i].mx=y;
    	return ;
        }
        int mid=(tre[i].l+tre[i].r)>>1;
        if (x>mid) modify(i*2+1,x,y);
        else modify(i*2,x,y);
        tre[i].data=tre[i*2].data+tre[i*2+1].data;
        tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
    }
    
    ll query(int i,int l,int r,int p)
    {
        if (tre[i].l==l && tre[i].r==r)
    	if (p) return tre[i].data;
    	else return tre[i].mx;
        int mid=(tre[i].l+tre[i].r)>>1;
        if (l>mid) return query(i*2+1,l,r,p);
        else if (r<=mid) return query(i*2,l,r,p);
        else if (p) return query(i*2,l,mid,p)+query(i*2+1,mid+1,r,p);
        else return max(query(i*2,l,mid,p),query(i*2+1,mid+1,r,p));
    }
    
    ll pathquery(int u,int v,int p)
    {
        ll ans=0,tmp=-1000000000;
        while (tp[u]!=tp[v])
        {
    	if (deep[tp[u]]<deep[tp[v]]) swap(u,v);
    	if (p) ans+=query(1,dfn[tp[u]],dfn[u],p);
    	else tmp=max(tmp,query(1,dfn[tp[u]],dfn[u],p));
    	u=f[tp[u]];
        }
        if (deep[u]>deep[v]) swap(u,v);
        if (p) return ans+query(1,dfn[u],dfn[v],p);
        else return max(tmp,query(1,dfn[u],dfn[v],p));
    }
    
    int main()
    {
        n=read();
        for (int i=1;i<n;i++)
        {
    	x=read();
    	y=read();
    	add(x,y);
    	add(y,x);
        }
        for (int i=1;i<=n;i++) a[i]=read();
        dfs1(1,0,0);
        dfs2(1,1);
        build(1,1,n);
        m=read();
        while (m--)
        {
    	scanf("%s",s);
    	x=read();
    	y=read();
    	if (s[1]=='M')
    	    printf("%lld
    ",pathquery(x,y,0));
    	else if (s[1]=='S')
    	    printf("%lld
    ",pathquery(x,y,1));
    	else modify(1,dfn[x],y);
        }
        return 0;
    }
    
  • 相关阅读:
    spring
    ajax
    jquary
    Java web 部分
    长跑马拉松
    面试的标准
    数据预处理——剔除异常值,平滑,归一化
    概率分布
    养生
    平滑的作用
  • 原文地址:https://www.cnblogs.com/mrha/p/7898884.html
Copyright © 2011-2022 走看看