2017 暑假艾教集训 day7 (树链剖分模板)

来源:互联网 发布:c语言temp怎么用 编辑:程序博客网 时间:2024/06/07 09:02


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,endint 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;}