• 【SHOI2012】魔法树(树链剖分,线段树)


    【SHOI2012】魔法树

    题面

    BZOJ上找不到这道题目
    只有洛谷上有。。
    所以粘贴洛谷的题面

    题解

    树链剖分之后直接维护线段树就可以了
    树链剖分良心模板题

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define MAX 110000
    #define lson (now<<1)
    #define rson (now<<1|1)
    #define ll long long
    inline int read()
    {
        register int x=0,t=1;
        register char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-'){t=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return x*t;
    }
    struct Node
    {
        long long s;
        long long ly;
    }t[MAX<<2];
    int tim;
    struct Line
    {
        int v,next;
    }e[MAX];
    int h[MAX],cnt=1;
    int dfn[MAX],low[MAX],dep[MAX],ff[MAX],size[MAX],hson[MAX],top[MAX];
    int line[MAX],N;
    inline void Add(int u,int v)
    {
        e[cnt]=(Line){v,h[u]};
        h[u]=cnt++;
    }
    void DFS1(int u)
    {
        dep[u]=dep[ff[u]]+1;size[u]=1;
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;
            DFS1(v);
            if(size[v]>size[hson[u]])hson[u]=v;
            size[u]+=size[v];
        }
    }
    void DFS2(int u,int tp)
    {
        top[u]=tp;dfn[u]=++tim;line[tim]=u;
        if(hson[u])DFS2(hson[u],tp);
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(v==hson[u])continue;
            DFS2(v,v);
        }
        low[u]=tim;
    }
    void pushup(int now)
    {
        t[now].s=t[lson].s+t[rson].s;
    }
    void putlazy(int now,int ly,int l,int r)
    {
        t[now].s+=1LL*(r-l+1)*ly;
        t[now].ly+=ly;
    }
    void pushdown(int now,int l,int r)
    {
        int mid=(l+r)>>1;
        putlazy(lson,t[now].ly,l,mid);
        putlazy(rson,t[now].ly,mid+1,r);
        t[now].ly=0;
    }
    void Modify(int now,int l,int r,int al,int ar,int d)
    {
        if(l==al&&r==ar){putlazy(now,d,l,r);return;}
        int mid=(l+r)>>1;
        t[now].s+=1LL*(ar-al+1)*d;
        if(ar<=mid)Modify(lson,l,mid,al,ar,d);
        else if(al>mid)Modify(rson,mid+1,r,al,ar,d);
        else {Modify(lson,l,mid,al,mid,d);Modify(rson,mid+1,r,mid+1,ar,d);}
    }
    ll Query(int now,int l,int r,int al,int ar)
    {
        if(l==al&&r==ar)return t[now].s;
        int mid=(l+r)>>1;
        pushdown(now,l,r);
        ll re=0;
        if(ar<=mid)re=Query(lson,l,mid,al,ar);
        else if(al>mid)re=Query(rson,mid+1,r,al,ar);
        else re=Query(lson,l,mid,al,mid)+Query(rson,mid+1,r,mid+1,ar);
        pushup(now);
        return re;
    }
    void LCA(int u,int v,int d)
    {
        while(top[u]!=top[v])
        {
            if(dep[top[u]]<dep[top[v]])swap(u,v);
            Modify(1,1,N,dfn[top[u]],dfn[u],d);
            u=ff[top[u]];
        }
        if(dep[v]>dep[u])swap(u,v);
        Modify(1,1,N,dfn[v],dfn[u],d);
    }
    int main()
    {
        N=read();
        for(int i=1;i<N;++i)
        {
            int x=read()+1,y=read()+1;
            ff[y]=x;
            Add(x,y);
        }
        DFS1(1);DFS2(1,1);
        int Q=read();
        while(Q--)
        {
            char ch[3];scanf("%s",ch);
            if(ch[0]=='A')
            {
                int u=read()+1,v=read()+1,d=read();
                LCA(u,v,d);
            }
            else
            {
                int u=read()+1;
                printf("%lld
    ",Query(1,1,N,dfn[u],low[u]));
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    Sql的基础知识(一)
    Django--分页功能
    django--基础操作
    CSRF攻击与防御(转载)
    谈谈CSRF
    浅谈Dom遍历
    node50行代码实现壁纸爬取
    node解决request中文乱码问题
    数组去重方法(转载)
    淘宝dns解析错误导致首页打不开
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7673874.html
Copyright © 2020-2023  润新知