2017 暑假艾教集訓 day7 (樹鏈剖分模板)


HDU 3966

樹鏈剖分模板題

#include <bits/stdc++.h>
using namespace std;
const int maxn= 50010;
int n,m,q;
int c[maxn];
int head[maxn],cnt=0;
struct node
{
    int to,next;
}edge[100005*2];

void add(int u,int v)
{
    edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++;
}

int fa[maxn],son[maxn],much[maxn],deep[maxn];
int pos[maxn],ndfs[maxn],top[maxn],tot=0;
void dfs1(int u,int pre,int step)
{
    fa[u]=pre;
    much[u]=1;
    deep[u]=step;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(v!=pre)
        {
            dfs1(v,u,step+1);
            much[u] += much[v];
            if(son[u]==-1 || much[v] > much[son[u]])    son[u]=v;
        }
    }
}

void dfs2(int u,int pre)
{
    top[u]= pre;
    ndfs[u] = ++tot;
    pos[ndfs[u]]=u;
    if(son[u]==-1) return;
    dfs2(son[u],pre);
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].to;
        if(v!=son[u] && v!=fa[u])
        {
            dfs2(v,v);
        }
    }
}
#define lson rt<<1,begin,mid
#define rson rt<<1|1,mid+1,end
int tree[maxn<<2],lazy[maxn<<2];

void pushdown(int rt,int k)
{
    if(lazy[rt])
    {
        int temp=lazy[rt];
        tree[rt<<1] +=(k-(k>>1))*temp;
        tree[rt<<1|1] += (k>>1)*temp;
        lazy[rt<<1] += temp;
        lazy[rt<<1|1] +=temp;

        lazy[rt]=0;
    }
}
void build(int rt,int begin,int end)
{
    lazy[rt]=0;
    if(begin==end)
    {
        tree[rt] = c[pos[begin]];
        return;
    }
    int mid=(begin + end)>>1;
    build(lson);
    build(rson);
}
int query(int rt,int begin,int end,int pos)
{
    if(begin == end)
    {
        return tree[rt];
    }
    pushdown(rt,end-begin+1);
    int mid = (begin + end)>>1;
    if(mid >= pos) return query(lson,pos);
    else return query(rson,pos);
}
void updata(int rt,int begin,int end,int l,int r,int x)
{
    if(begin >=l && r>=end)
    {
        lazy[rt]+=x;
        tree[rt]+= x*(end-begin+1);
        return;
    }
    pushdown(rt,end-begin+1);
    int mid=(begin + end)>>1;
    if(mid >= l) updata(lson,l,r,x);
    if(r>mid) updata(rson,l,r,x);
}
void chang(int x,int y,int val)
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]] < deep[top[y]]) swap(x,y);
        updata(1,1,n,ndfs[top[x]],ndfs[x],val);
        x = fa[top[x]];
    }
    if(deep[x]  > deep[y])  swap(x,y);
    updata(1,1,n,ndfs[x],ndfs[y],val);
}

char s[25];
int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        memset(head,-1,sizeof(head)); cnt=0;
        memset(son,-1,sizeof(son)); tot=0;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&c[i]);
        }
        for(int i=1;i<=m;++i)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b); add(b,a);
        }
        dfs1(1,0,0);
        dfs2(1,1);
        build(1,1,n);
        for(int i=1;i<=q;++i)
        {
            scanf("%s",s);
            if(s[0]=='I')
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                chang(a,b,c);
            }
            else if(s[0]=='D')
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                chang(a,b,-c);
            }
            else if(s[0]=='Q')
            {
                int a;
                scanf("%d",&a);
                printf("%d\n",query(1,1,n,ndfs[a]));
            }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章