HDU 3966 树链剖分 点权

来源:互联网 发布:程序员必备电子产品 编辑:程序博客网 时间:2024/05/21 10:24

练手的模板题...成段更新,单点查询....点权不同于边权,稍微做一些处理就可以搞定了。

不自觉就用了线段树的lazy操作,不用复杂度似乎可以承受?

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<iostream>using namespace std;#define MAXN 103000struct edge{    int v,next;}edge[MAXN*2];int fa[MAXN],son[MAXN];int p[MAXN],fp[MAXN];int num[MAXN],dep[MAXN];int top[MAXN],pos;int head[MAXN],t;void inti(){    t=0;    memset(head,-1,sizeof(head));    pos=1;    memset(son,-1,sizeof(son));}void add(int u,int v){    edge[t].v=v;    edge[t].next=head[u];    head[u]=t++;}void dfs1(int u,int d){    dep[u]=d;    num[u]=1;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(v!=fa[u])        {            fa[v]=u;            dfs1(v,d+1);            num[u]+=num[v];            if(son[u]==-1||num[v]>num[son[u]])                son[u]=v;        }    }}void dfs2(int u,int sp){    top[u]=sp;    p[u]=pos++;    fp[p[u]]=u;    if(son[u]==-1) return ;    dfs2(son[u],sp);    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(v!=fa[u]&&v!=son[u])            dfs2(v,v);    }}struct node{    int l,r,cover;}data[MAXN*4];void build(int l,int r,int k){    data[k].l=l;    data[k].r=r;    data[k].cover=0;    if(l==r) return ;    int mid=(l+r)/2;    build(l,mid,k*2);    build(mid+1,r,k*2+1);}void updata(int k,int l,int r,int val){    if(data[k].l==l&&data[k].r==r)    {        data[k].cover+=val;        return ;    }    if(data[k].cover!=0)    {        data[k*2].cover+=data[k].cover;        data[k*2+1].cover+=data[k].cover;        data[k].cover=0;    }    int mid=(data[k].l+data[k].r)/2;    if(r<=mid) updata(k*2,l,r,val);    else if(l>mid) updata(k*2+1,l,r,val);    else    {        updata(k*2,l,mid,val);        updata(k*2+1,mid+1,r,val);    }}int query(int x,int k){    if(data[k].l==data[k].r&&data[k].l==x)    {        return data[k].cover;    }    if(data[k].cover!=0)    {        data[k*2].cover+=data[k].cover;        data[k*2+1].cover+=data[k].cover;        data[k].cover=0;    }    int mid=(data[k].l+data[k].r)/2;    if(x<=mid)        return query(x,k*2);    else        return query(x,k*2+1);}void change(int u,int v,int w){    int f1=top[u];    int f2=top[v];    while(f1!=f2)    {        if(dep[f1]<dep[f2])        {            swap(f1,f2);            swap(u,v);        }        updata(1,p[f1],p[u],w);        u=fa[f1];        f1=top[u];    }    if(dep[u]>dep[v]) swap(u,v);    updata(1,p[u],p[v],w);}int a[MAXN];int main(){    int n,m,q;    while(scanf("%d%d%d",&n,&m,&q)!=EOF)    {        inti();        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        int u,v,w;        for(int i=0;i<m;i++)        {            scanf("%d%d",&u,&v);            add(u,v);            add(v,u);        }        dfs1(1,1);        dfs2(1,1);        build(1,n,1);        char op[100];        while(q--)        {            scanf("%s",op);            if(op[0]=='I')            {                scanf("%d%d%d",&u,&v,&w);                change(u,v,w);            }            else if(op[0]=='D')            {                scanf("%d%d%d",&u,&v,&w);                change(u,v,-w);            }            else            {                scanf("%d",&u);                printf("%d\n",query(p[u],1)+a[u]);            }        }    }    return 0;}


0 0