首页 > 代码库 > 树链剖分
树链剖分
#include<iostream>#include<cstring>#include<set>#include<map>#include<cmath>#include<stack>#include<queue>#include<deque>#include<list>#include<algorithm>#include<stdio.h>#include<iomanip>#define rep(i,n) for(int i=0;i<n;++i)#define fab(i,a,b) for(int i=a;i<=b;++i)#define fba(i,b,a) for(int i=b;i>=a;--i)#define PB push_back#define INF 0x3f3f3f3f#define MP make_pair#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define sf scanf#define pf printf#define LL long longconst int N=30005;using namespace std;typedef pair<int,int>PII;int top[N];int n,father[N],dep[N],son[N],size[N],tree[N],id[N];int value[N];struct Edge{int v,next;}E[N*3];int ecnt,tcnt;int head[N];int sum[N<<2],maxv[N<<2];void addedge(int u,int v){ E[ecnt].v=v; E[ecnt].next=head[u]; head[u]=ecnt++;}void init(){ memset(head,-1,sizeof head); memset(son,0,sizeof son); ecnt=0; tcnt=0;}char C;void read(int &x){ while(C=getchar(),C<‘0‘||C>‘9‘);x=C-‘0‘; while(C=getchar(),C>=‘0‘&&C<=‘9‘)x=x*10+C-‘0‘;}void input(){ int u,v; for(int i=1;i<n;i++){ read(u);read(v); addedge(u,v); addedge(v,u); } fab(i,1,n){ sf("%d",&value[i]); //read(value[i]); }}void dfs1(int u,int fa,int d){ dep[u]=d; father[u]=fa; size[u]=1; for(int i=head[u];~i;i=E[i].next){ int v=E[i].v; if(v==fa)continue; dfs1(v,u,d+1); size[u]+=size[v]; if(!son[u]||size[v]>size[son[u]])son[u]=v; }}void dfs2(int u,int t){ top[u]=t; tree[u]=++tcnt; id[tcnt]=u; if(!son[u])return; dfs2(son[u],t); for(int i=head[u];~i;i=E[i].next){ int v=E[i].v; if(v!=son[u]&&v!=father[u])dfs2(v,v); }}void push_up(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);}void build(int l,int r,int rt){ if(l==r){ sum[rt]=maxv[rt]=value[id[l]]; return; } int m=(l+r)>>1; build(lson); build(rson); push_up(rt);}int query_max(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return maxv[rt]; } int m=(l+r)>>1; int ret=-INF; if(L<=m)ret=max(ret,query_max(L,R,lson)); if(R>m)ret=max(ret,query_max(L,R,rson)); return ret;}int findmax(int L,int R){ int f1=top[L],f2=top[R],ret=-INF; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(L,R); } ret=max(ret,query_max(tree[f1],tree[L],1,n,1)); L=father[f1]; f1=top[L]; } if(dep[L]<dep[R])swap(L,R); ret=max(ret,query_max(tree[R],tree[L],1,n,1)); return ret;}void update(int p,int v,int l,int r,int rt){ if(l==r){ maxv[rt]=sum[rt]=v; return ; } int m=(l+r)>>1; if(p<=m)update(p,v,lson); else if(p>m)update(p,v,rson); push_up(rt);}int query_sum(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return sum[rt]; } int m=(l+r)>>1; int ret=0; if(L<=m)ret+=query_sum(L,R,lson); if(R>m)ret+=query_sum(L,R,rson); return ret;}int findsum(int L,int R){ int f1=top[L],f2=top[R],ret=0; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(L,R); } ret+=query_sum(tree[f1],tree[L],1,n,1); L=father[f1]; f1=top[L]; } if(dep[L]<dep[R])swap(L,R); ret+=query_sum(tree[R],tree[L],1,n,1); return ret;}void print(int a){ if(a<0){ putchar(‘-‘); a=-a; } if(a>=10)print(a/10); putchar(a%10+‘0‘);}void solve(){ dfs1(1,0,1); dfs2(1,1); build(1,n,1); int Q;sf("%d",&Q); char op[20]; int x,y; while(Q--){ sf("%s %d %d",op,&x,&y); if(op[0]==‘C‘)update(tree[x],y,1,n,1),value[x]=y; else if(op[1]==‘M‘)print(findmax(x,y)),puts(""); else print(findsum(x,y)),puts(""); }}int main(){ while(~sf("%d",&n)){ init(); input(); solve(); } return 0;}
树链剖分
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。