HDU 3966 树链剖分

来源:互联网 发布:制作传单的软件 编辑:程序博客网 时间:2024/06/05 00:37

同上,区间更新,单点查询。

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define eps  1e-12#define INF   0x7fffffff#define maxn 100010using namespace std;#pragma comment(linker,"/STACk:10240000,10240000")struct node{    int to,next;} e[maxn<<1];int head[maxn],en,n;int fa[maxn],siz[maxn],top[maxn],son[maxn],w[maxn],dep[maxn],id;int num[maxn<<2];int col[maxn<<2];void init(){    fa[1]=0;    dep[1]=0;    id=en=0;    memset(head,-1,sizeof(head));    memset(siz,0,sizeof(siz));    memset(num,0,sizeof(num));    memset(col,0,sizeof(col));}void add(int a,int b){    e[en].to=b;    e[en].next=head[a];    head[a]=en++;}void dfs(int now){    siz[now]=1;    son[now]=0;    for(int i=head[now]; ~i; i=e[i].next)    {        int to=e[i].to;        if(to!=fa[now])        {            fa[to]=now;            dep[to]=dep[now]+1;            dfs(to);            if(siz[to]>siz[son[now]]) son[now]=to;            siz[now]+=siz[to];        }    }}void getid(int now,int root){    w[now]=++id;    top[now]=root;    if(son[now]) getid(son[now],top[now]);    for(int i=head[now]; ~i; i=e[i].next)    {        if(e[i].to!=son[now]&&e[i].to!=fa[now])        {            getid(e[i].to,e[i].to);        }    }}void pushdown(int rt){    if(col[rt])    {        num[rt<<1]+=col[rt];        num[rt<<1|1]+=col[rt];        col[rt<<1]+=col[rt];        col[rt<<1|1]+=col[rt];        col[rt]=0;    }}void update(int rt,int l,int r,int ql,int qr,int add){    if(ql<=l&&r<=qr)    {        num[rt]+=add;        col[rt]+=add;        return ;    }    int mid=(l+r)/2,lson=(rt<<1),rson=(rt<<1|1);   // pushdown(rt);    if(ql<=mid) update(lson,l,mid,ql,qr,add);    if(qr>mid)  update(rson,mid+1,r,ql,qr,add);}int querysum(int rt,int l,int r,int k){    if(l==r) return num[rt];    int mid=(l+r)/2,lson=(rt<<1),rson=(rt<<1|1);    pushdown(rt);    if(k<=mid) return querysum(lson,l,mid,k);    else return querysum(rson,mid+1,r,k);}void change(int x,int y,int val){    while(top[x]!=top[y])    {        if(dep[top[x]]<dep[top[y]]) swap(x,y);        update(1,1,n,w[top[x]],w[x],val);        x=fa[top[x]];    }    if(dep[x]>dep[y]) swap(x,y);    update(1,1,n,w[x],w[y],val);}int save[maxn];int main(){    char str[5];    int a,b,c,m,k;    while(~scanf("%d%d%d",&n,&m,&k))    {        init();        for(int i=1; i<=n; i++)        {            scanf("%d",&save[i]);        }        for(int i=1; i<=m; i++)        {            scanf("%d%d",&a,&b);            add(a,b);            add(b,a);        }        dfs(1);        getid(1,1);        for(int i=1; i<=n; i++)        {            update(1,1,n,w[i],w[i],save[i]);        }        while(k--)        {            scanf("%s",str);            if(str[0]=='Q')            {                scanf("%d",&a);                printf("%d\n",querysum(1,1,n,w[a]));            }            else if(str[0]=='D')            {                scanf("%d%d%d",&a,&b,&c);                change(a,b,-c);            }            else            {                scanf("%d%d%d",&a,&b,&c);                change(a,b,c);            }        }    }    return 0;}


4 0
原创粉丝点击