天天看点

Aragorn's Story

​​A - Aragorn's Story​​

直接套 线段树+树剖 板子

代码:

// Created by CAD on 2019/8/12.
#include <bits/stdc++.h>
#define lson (p<<1)
#define rson (p<<1|1)
using namespace std;
using ll=long long;
const int maxn=5e4+5;
ll d[maxn<<2],laz[maxn<<2];
int wt[maxn],w[maxn],head[maxn],dep[maxn];
int id[maxn],son[maxn],f[maxn],siz[maxn],top[maxn];
int tot,cnt,n;
void build(int l,int r,int p)
{
    laz[p]=0;
    if(l==r)
    {
        d[p]=wt[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,lson),build(m+1,r,rson);
    d[p]=d[lson]+d[rson];
}
void pushdown(int s, int t,int p)
{
    int m=(s+t)>>1;
    d[lson]+=(m-s+1)*laz[p],d[rson]+=(t-m)*laz[p];
    laz[lson]+=laz[p],laz[rson]+=laz[p];
    laz[p]=0;
}
void update(int l,int r,int s,int t,int c,int p)
{
    if(l<=s&&t<=r)
    {
        d[p]+=(t-s+1)*c;
        laz[p]+=c;
        return ;
    }
    if(laz[p]) pushdown(s,t,p);
    int m=(s+t)>>1;
    if(l<=m) update(l,r,s,m,c,lson);
    if(r>m) update(l,r,m+1,t,c,rson);
    d[p]=d[lson]+d[rson];
}
ll getsum(int l,int r,int s,int t,int p)
{
    if(l<=s&&t<=r)
        return d[p];
    if(laz[p]) pushdown(s,t,p);
    int m=(s+t)>>1;
    if(l<=m) return getsum(l,r,s,m,lson);
    else return getsum(l,r,m+1,t,rson);
}
struct edge{
    int to,next;
}e[maxn<<1];
void add(int u,int v)
{
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void dfs1(int u,int fa,int deep)
{
    dep[u]=deep;
    f[u]=fa;
    siz[u]=1;
    int maxson=-1;
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v==fa) continue;
        dfs1(v,u,deep+1);
        siz[u]+=siz[v];
        if(siz[v]>maxson)
            maxson=siz[v],son[u]=v;
    }
}
void dfs2(int u,int topf)
{
    top[u]=topf;
    id[u]=++tot;
    wt[tot]=w[u];
    if(!son[u]) return ;
    dfs2(son[u],topf);
    for(int i=head[u];i;i=e[i].next)
    {
        int v=e[i].to;
        if(v==f[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}
void updrange(int x,int y,int k)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(id[top[x]],id[x],1,n,k,1);
        x=f[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(id[x],id[y],1,n,k,1);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int m,p;
    while(cin>>n>>m>>p)
    {
        cnt=tot=0;
        for(int i=1;i<=n;++i) head[i]=0,son[i]=0,siz[i]=0;
        for(int i=1;i<=n;++i) cin>>w[i];
        for(int i=1,u,v;i<=m;++i) cin>>u>>v,add(u,v),add(v,u);
        dfs1(1,0,1);
        dfs2(1,1);
        build(1,n,1);
        for(int i=1;i<=p;++i)
        {
            string op;
            cin>>op;
            int x,y,k;
            if(op=="I")
                cin>>x>>y>>k,updrange(x,y,k);
            else if(op=="D")
                cin>>x>>y>>k,updrange(x,y,-k);
            else if(op=="Q")
                cin>>x,cout<<getsum(id[x],id[x],1,n,1)<<endl;
        }
    }
    return 0;
}