bzoj1036 codevs2460: [ZJOI2008]树的统计 树链剖分
2014-09-10 17:28
267 查看
简单树链抛分,竟然总是dfs写错。。。。。不能忍。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> using namespace std; #define maxn 60000 #define ll long long #define lson rt<<1,l,m #define rson rt<<1|1,m+1,r #define INF 0x7fffffff int fa[maxn],siz[maxn],top[maxn],w[maxn],son[maxn],dep[maxn],id; struct node { int v,next; }g[maxn]; int num,n,first[maxn],val[maxn]; int tree[maxn<<1],sum[maxn<<1]; void build(int a,int b) { num++; g[num].v=b; g[num].next=first[a]; first[a]=num; } void dfs(int now) { int v,ceng; int maxv=0,flag=0; siz[now]=1; for(int i=first[now];i;i=g[i].next) { v=g[i].v; if(v==fa[now]) continue; dep[v]=dep[now]+1; fa[v]=now; dfs(v); siz[now]+=siz[v]; if(siz[v]>maxv) { maxv=siz[v]; flag=v; } } son[now]=flag; } void getid(int now,int root) { w[now]=++id; top[now]=root; if(son[now]) getid(son[now],top[now]); for(int i=first[now]; i; i=g[i].next) { if(g[i].v!=son[now]&&g[i].v!=fa[now]) { getid(g[i].v,g[i].v); } } } void pushup(int rt) { sum[rt]=sum[(rt<<1)]+sum[(rt<<1|1)]; tree[rt]=max(tree[(rt<<1)],tree[(rt<<1|1)]); } void update(int rt,int l,int r,int x,int add) { if(l==r) { tree[rt]=sum[rt]=add; return; } int m=(l+r)>>1; if(x<=m) { update(lson,x,add); } if(x>m) { update(rson,x,add); } pushup(rt); } int querymax(int rt,int l,int r,int x,int y) { if(l>=x&&y>=r) { return tree[rt]; } int tmp=-INF; int m=(l+r)>>1; if(x<=m) { tmp=max(tmp,querymax(lson,x,y)); } if(y>m) { tmp=max(tmp,querymax(rson,x,y)); } return tmp; } int querysum(int rt,int l,int r,int x,int y) { if(l>=x&&y>=r) { return sum[rt]; } int tmp=0; int m=(l+r)>>1; if(x<=m) { tmp+=querysum(lson,x,y); } if(y>m) { tmp+=querysum(rson,x,y); } return tmp; } int getans(int x,int y,int op) { int ans=-INF,asum=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) { swap(x,y); } if(op==1) { ans=max(ans,querymax(1,1,n,w[top[x]],w[x])); } else { asum+=querysum(1,1,n,w[top[x]],w[x]); } x=fa[top[x]]; } if(op==1) { if(dep[x]>dep[y]) ans=max(ans,querymax(1,1,n,w[y],w[x])); else ans=max(ans,querymax(1,1,n,w[x],w[y])); } else { if(dep[x]>dep[y]) asum+=querysum(1,1,n,w[y],w[x]); else asum+=querysum(1,1,n,w[x],w[y]); } if(op==1) return ans; else return asum; } int main() { char str[20]; int a,b,c; scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); build(a,b); build(b,a); } dfs(1); //printf("orzn"); getid(1,1); //printf("orzn"); for(int i=1;i<=n;i++) { scanf("%d",&val[i]); update(1,1,n,w[i],val[i]); } scanf("%d",&c); while(c--) { scanf("%s%d%d",str,&a,&b); if(str[1]=='M') { printf("%d\n",getans(a,b,1)); } else if(str[1]=='S') { printf("%d\n",getans(a,b,2)); } else { update(1,1,n,w[a],b); } } return 0; } /* 4 1 2 2 3 4 1 4 2 1 3 12 QMAX 3 4 QMAX 3 3 QMAX 3 2 QMAX 2 3 QSUM 3 4 QSUM 2 1 CHANGE 1 5 QMAX 3 4 CHANGE 3 6 QMAX 3 4 QMAX 2 4 QSUM 3 4 */
相关文章推荐
- BZOJ_P1036&Codevs_P2460 [ZJOI2008]树的统计Count(树链剖分)
- 【codevs2460】【BZOJ1036】树的统计count,第一次的树链剖分
- BZOJ 1036 [ZJOI2008] 树的统计Count (树链剖分)
- BZOJ 1036: [ZJOI2008]树的统计Count 树链剖分
- 【BZOJ 1036】【ZJOI 2008】树的统计 树链剖分模板题
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- 树链剖分教程 & bzoj 1036 [ZJOI2008] 树的统计 Count 题解
- BZOJ 1036 [ZJOI2008]树的统计Count 树链剖分练手题
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
- 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count
- bzoj1036: [ZJOI2008]树的统计Count - 树链剖分
- BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】
- BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分裸题)
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- BZOJ 1036: [ZJOI2008]树的统计Count 树链剖分
- kyeremal-bzoj1036[ZJOI2008]-树的统计count-树链剖分
- 【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
- BZOJ 1036([ZJOI2008]树的统计Count-树链剖分[成熟版])