hdu 3966 树链剖分
思路:树链剖分入门题,我这门入得好苦啊,程序很快写出来了,可是在LCA过程中把update函数里的左右边界位置写反了,一直RE到死。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pb push_back #define mp make_pair #define Maxn 50010 #define Maxm 200010 #define LL __int64 #define Abs(x) ((x)>0?(x):(-x)) #define lson(x) (x<<1) #define rson(x) (x<<1|1) #define inf 100000 #define lowbit(x) (x&(-x)) #define clr(x,y) memset(x,y,sizeof(x)) #define Mod 1000000007 using namespace std; int head[Maxn],vi[Maxn],dep[Maxn],w[Maxn],top[Maxn],son[Maxn],sz[Maxn],fa[Maxn],e,id; int num[Maxn]; struct Edge{ int u,v,next; }edge[Maxn*3]; struct Tree{ int l,r,c; int mid(){ return (l+r)>>1; } }tree[Maxn*3]; void init() { clr(head,-1);clr(vi,0); e=0;id=0; } void add(int u,int v) { edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++; } void BuildTree(int l,int r,int po) { tree[po].l=l,tree[po].r=r,tree[po].c=0; if(l==r) return ; int mid=tree[po].mid(); BuildTree(l,mid,lson(po)); BuildTree(mid+1,r,rson(po)); } void down(int po) { tree[lson(po)].c+=tree[po].c; tree[rson(po)].c+=tree[po].c; tree[po].c=0; } void update(int l,int r,int c,int po) { if(l<=tree[po].l&&tree[po].r<=r){ tree[po].c+=c; return ; } down(po); int mid=tree[po].mid(); if(r<=mid) update(l,r,c,lson(po)); else if(l>=mid+1) update(l,r,c,rson(po)); else { update(l,mid,c,lson(po)); update(mid+1,r,c,rson(po)); } } int getans(int i,int po) { if(tree[po].l==tree[po].r){ return tree[po].c; } down(po); int mid=tree[po].mid(); if(i<=mid) return getans(i,lson(po)); else return getans(i,rson(po)); } void dfs(int u) { vi[u]=1; int i,v; son[u]=0,sz[u]=1; for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(vi[v]) continue; dep[v]=dep[u]+1; fa[v]=u; dfs(v); if(sz[v]>sz[son[u]])son[u]=v; sz[u]+=sz[v]; } } void build(int u,int ti) { int i,v; w[u]=++id;top[u]=ti;vi[u]=1; if(son[u]) build(son[u],ti); for(i=head[u];i!=-1;i=edge[i].next){ v=edge[i].v; if(vi[v]||v==son[u]) continue; build(v,v); } } void calc(int u,int v,int c) { int f1=top[u],f2=top[v]; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2),swap(u,v); } update(w[f1],w[u],c,1); u=fa[f1];f1=top[u]; } if(dep[u]>dep[v]) swap(u,v); update(w[u],w[v],c,1); return ; } int main() { int n,m,p,i,j,u,v,val; char str[10]; while(scanf("%d%d%d",&n,&m,&p)!=EOF){ init(); for(i=1;i<=n;i++) scanf("%d",num+i); for(i=1;i<=m;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1); clr(vi,0); build(1,1); BuildTree(1,id,1); int ans; for(i=1;i<=p;i++){ scanf("%s",str); if(str[0]=='I'){ scanf("%d%d%d",&u,&v,&val); calc(u,v,val); } else if(str[0]=='D'){ scanf("%d%d%d",&u,&v,&val); calc(u,v,-val); }else { scanf("%d",&u); ans=getans(w[u],1); printf("%d\n",num[u]+ans); } } } return 0; }