HDU3966(树链剖分) 模板题

来源:互联网 发布:凯立德找不到导航软件 编辑:程序博客网 时间:2024/05/17 00:54

呃…学习的话有个链接http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
(对没错,我就是来贴代码的…因为CF有道题要用树链剖分所以 学习了一下

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<string>#include<vector>#include<map>#include<set>using namespace std;#define rfor(i,a,b) for(i=a;i<=b;++i)#define lfor(i,a,b) for(i=a;i>=b;--i)#define sfor(i,a,h) for(i=h[a];i!=-1;i=e[i].next)#define mem(a,b) memset(a,b,sizeof(a))#define mec(a,b) memcpy(a,b,sizeof(b))#define cheak(i) printf("%d ",i)#define min(a,b) (a>b?b:a)#define max(a,b) (a>b?a:b)#define inf 0x3f3f3f3f#define lowbit(x) (x&(-x))typedef long long LL;#define maxn 50010#define maxm maxn*maxn#define lson(x) (splay[x].son[0])#define rson(x) (splay[x].son[1])int n,m,q,tim;int num[maxn],siz[maxn],top[maxn],son[maxn];int dep[maxn],tid[maxn],Rank[maxn],fa[maxn];struct node{    int next,sta,to;}e[maxn*2];int tot,h[maxn];void add_edge(int a,int b){    e[++tot].next=h[a];    e[tot].sta=a;    e[tot].to=b;    h[a]=tot;}void init(){    mem(h,-1);mem(son,-1);    tim=0;tot=0;}//树链剖分 void dfs1(int u,int father,int d){    dep[u]=d;fa[u]=father;    siz[u]=1;    for(int i=h[u];i!=-1;i=e[i].next)    {        int v=e[i].to;        if(v!=father)        {            dfs1(v,u,d+1);            siz[u]+=siz[v];            if(son[u]==-1||siz[v]>siz[son[u]])            son[u]=v;        }    }}void dfs2(int u,int tp){    top[u]=tp;tid[u]=++tim;    Rank[tim]=u;    if(son[u]==-1) return ;    dfs2(son[u],tp);    for(int i=h[u];i!=-1;i=e[i].next)    {        int v=e[i].to;        if(v!=son[u]&&v!=fa[u])        dfs2(v,v);    }}//segmentstruct Tree{    int sum,col;}tree[maxn*4]; void Push_up(int index){    tree[index].sum=max(tree[index*2].sum,tree[index*2+1].sum);}void Push_down(int index,int k){    if(tree[index].col)    {        tree[index*2].col+=tree[index].col;        tree[index*2+1].col+=tree[index].col;        tree[index*2].sum+=(k-k/2)*tree[index].col;        tree[index*2+1].sum+=(k/2)*tree[index].col;        tree[index].col=0;    }}void build(int l,int r,int index){    tree[index].col=0;    if(l==r)    {        tree[index].sum=num[Rank[l]];        return ;    }    int mid=(l+r)/2;    build(l,mid,index*2);    build(mid+1,r,index*2+1);    Push_up(index);}int query(int l,int r,int index,int val){    if(l==r) return tree[index].sum;    Push_down(index,r-l+1);    int mid=(l+r)/2;    int ret=0;    if(val<=mid)    ret=query(l,mid,index*2,val);    else ret=query(mid+1,r,index*2+1,val);    Push_up(index);    return ret;}void update(int L,int R,int val,int l,int r,int index){    if(L<=l&&R>=r)    {        tree[index].col+=val;        tree[index].sum+=val*(r-l+1);        return ;    }    Push_down(index,r-l+1);    int mid=(l+r)/2;    if(L<=mid)    update(L,R,val,l,mid,index*2);    if(R>mid)    update(L,R,val,mid+1,r,index*2+1);    Push_up(index);}void Change(int x,int y,int val){    while(top[x]!=top[y])    {        if(dep[top[x]]<dep[top[y]]) swap(x,y);        update(tid[top[x]],tid[x],val,1,n,1);        x=fa[top[x]];    }    if(dep[x]>dep[y]) swap(x,y);    update(tid[x],tid[y],val,1,n,1);}int main(){    int i,k,a,b,c;    while(~scanf("%d%d%d",&n,&m,&k))    {        init();        rfor(i,1,n) scanf("%d",&num[i]);        rfor(i,1,m)        {            scanf("%d%d",&a,&b);            add_edge(a,b);add_edge(b,a);        }        dfs1(1,0,0);        dfs2(1,1);        build(1,n,1);        while(k--)        {            char oper[5];            scanf("%s",oper);            if(oper[0]=='Q')            {                scanf("%d",&a);                printf("%d\n",query(1,n,1,tid[a]));            }            else            {                scanf("%d%d%d",&a,&b,&c);                if(oper[0]=='D') c=-c;                Change(a,b,c);            }        }    }    return 0;}
0 0