HDU3966 Aragorn's Story 树链剖分+线段树

树链剖分裸题不解释

#include <vector>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

const int MAXN=1000010+2;
struct HASH{
	int u;
	HASH *next;
	HASH(){}
	HASH(int _u,HASH *_next):u(_u),next(_next){}
}*table[MAXN],mem[2*MAXN];
typedef struct NODE{
	int s,l,r,add;
	NODE *lchild,*rchild;
	NODE(){}
	NODE(int _l,int _r):l(_l),r(_r),s(0),add(0),lchild(0),rchild(0){}
} *TREE;
TREE root;
int N,M,Q;
int v[MAXN],c[MAXN],f[MAXN],d[MAXN],tab[MAXN],mark1[MAXN],mark2[MAXN],son[MAXN],cnt;
char s;

void Insert(int u,int v){ table[u]=&(mem[cnt++]=HASH(v,table[u]));}

void DFS1(int u,int fa,int deep){
	c[u]=1,f[u]=fa,d[u]=deep;
	for(HASH *p=table[u];p;p=p->next)
		if(p->u!=f[u]){
			DFS1(p->u,u,deep+1);
			c[u]+=c[p->u];
			if(son[u]==-1 || c[p->u]>c[son[u]]) son[u]=p->u;
		}
}

void DFS2(int u,int t){
	tab[u]=t,mark1[u]=++cnt,mark2[cnt]=u;
	if(son[u]==-1) return;
	DFS2(son[u],t);
	for(HASH *p=table[u];p;p=p->next)
		if(p->u!=f[u] && p->u!=son[u]) DFS2(p->u,p->u);
}

void Pushup(TREE &x){ x->s=x->lchild->s+x->rchild->s;}

void Pushdown(TREE &x,int m){
    if(x->add){
        x->lchild->s+=x->add*(m-(m>>1));
        x->rchild->s+=x->add*(m>>1);
        x->lchild->add+=x->add,x->rchild->add+=x->add;
        x->add=0;
    }
}

void Build(TREE &x,int l,int r){
	x=new NODE(l,r);
	if(l==r){
		x->s=v[mark2[l]];
		return;
	}

	int m=(l+r)>>1;
	Build(x->lchild,l,m),Build(x->rchild,m+1,r);

	Pushup(x);
}

void Update(TREE &x,int l,int r,int add){
    if(l<=x->l && r>=x->r){
        x->add+=add,x->s+=add*(x->r-x->l+1);
        return;
    }

    Pushdown(x,x->r-x->l+1);

    int m=(x->l+x->r)>>1;
    if(l<=m) Update(x->lchild,l,r,add);
    if(r>m) Update(x->rchild,l,r,add);

    Pushup(x);
}

void Change(int u,int v,int w){
    while(tab[u]!=tab[v]){
        if(d[tab[u]]<d[tab[v]]) swap(u,v);
        Update(root,mark1[tab[u]],mark1[u],w);
        u=f[tab[u]];
    }
    if(d[u]>d[v]) swap(u,v);
    Update(root,mark1[u],mark1[v],w);
}

int Query(TREE &x,int p){
    if(x->l==p && x->r==p) return x->s;

    Pushdown(x,x->r-x->l+1);

    int m=(x->l+x->r)>>1,ret=0;
    if(p<=m) ret=Query(x->lchild,p);
    else ret=Query(x->rchild,p);

    Pushup(x);
    return ret;
}

void Erase(TREE x){
    if(!x) return;
    Erase(x->lchild),Erase(x->rchild);
    delete x;
}

int main(){
    while(~scanf("%d %d %d",&N,&M,&Q)){
        memset(son,-1,sizeof(son));
        memset(table,0,sizeof(table));

        for(int i=1;i<=N;i++) cin >> v[i];
        for(int i=1,u,v;i<=M;i++){
            cin >> u >> v;
            Insert(u,v),Insert(v,u);
        }

        cnt=0,DFS1(1,0,1);
        cnt=0,DFS2(1,1);
        Build(root,1,N);

        for(int i=1,C1,C2,K;i<=Q;i++){
            cin >> s;
            if(s=='I'){
                cin >> C1 >> C2 >> K;
                Change(C1,C2,K);
            }
            if(s=='D'){
                cin >> C1 >> C2 >> K;
                Change(C1,C2,-K);
            }
            if(s=='Q'){
                cin >> C1;
                cout << Query(root,mark1[C1]) << endl;
            }
        }

        Erase(root);
    }

	return 0;
}


你可能感兴趣的:(HDU3966 Aragorn's Story 树链剖分+线段树)