HYSBZ1036 树链剖分
2016-01-15 19:59
501 查看
这题我建了2棵线段树,这样来处理 最值和和值,简单的题目。
#include<queue> #include<stack> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 #define ll __int64 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN = 50010; struct node { int to; int v; int next; }edge[MAXN*3]; int pre[MAXN],ind,top[MAXN],fa[MAXN],son[MAXN],w[MAXN],deq[MAXN],siz[MAXN],fn; int tree1[MAXN<<2],tree2[MAXN<<2]; int n,val[MAXN]; void add(int x,int y) { edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind++; } void dfs1(int rt,int pa,int d) { deq[rt] = d; son[rt] = 0; fa[rt] = pa; siz[rt] = 1; for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(t != fa[rt]){ dfs1(t,rt,d+1); siz[rt] += siz[t]; if(siz[son[rt]] < siz[t]){ son[rt] = t; } } } } void dfs2(int rt,int tp) { w[rt] = ++ fn; top[rt] = tp; if(son[rt] != 0) dfs2(son[rt],tp); for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(son[rt] != t && t != fa[rt]){ dfs2(t,t); } } } void pushup1(int rt) { tree1[rt] = max(tree1[rt<<1],tree1[rt<<1|1]); } void pushup2(int rt) { tree2[rt] = tree2[rt<<1] + tree2[rt<<1|1]; } void Insert(int p,int v,int l,int r,int rt) { if(l == r){ tree1[rt] = tree2[rt] = v; return ; } int m = (l+r)/2; if(m >= p){ Insert(p,v,lson); } else { Insert(p,v,rson); } pushup1(rt); pushup2(rt); } void updata(int p,int v,int l,int r,int rt) { if(l == r){ tree1[rt] = v; tree2[rt] = v; return ; } int m = (l+r)/2; if(m >= p){ updata(p,v,lson); } else { updata(p,v,rson); } pushup1(rt); pushup2(rt); } int query1(int L,int R,int l,int r,int rt) { if(L<=l && r<=R){ return tree1[rt]; } int m = (l+r)/2; int ans = -INF; if(m >= L){ ans = max(ans,query1(L,R,lson)); } if(m < R){ ans = max(ans,query1(L,R,rson)); } return ans; } int query2(int L,int R,int l,int r,int rt) { if(L<=l && r<=R){ return tree2[rt]; } int m = (l+r)/2; int ans = 0; if(m >= L){ ans += query2(L,R,lson); } if(m < R){ ans += query2(L,R,rson); } return ans; } int Getmax(int x,int y) { int ans = -INF; while(top[x] != top[y]) { if(deq[top[x]] < deq[top[y]]){ swap(x,y); } ans = max(ans,query1(w[top[x]],w[x],1,fn,1)); x = fa[top[x]]; } if(deq[x] < deq[y]){ swap(x,y); } ans = max(ans,query1(w[y],w[x],1,fn,1)); return ans; } int Getsum(int x,int y) { int ans = 0; while(top[x] != top[y]) { if(deq[top[x]] < deq[top[y]]){ swap(x,y); } ans += query2(w[top[x]],w[x],1,fn,1); x = fa[top[x]]; } if(deq[x] < deq[y]){ swap(x,y); } ans += query2(w[y],w[x],1,fn,1); return ans; } int main() { int i; while(~scanf("%d",&n)) { ind = 1; memset(pre,-1,sizeof(pre)); memset(tree1,0,sizeof(tree1)); memset(tree2,0,sizeof(tree2)); for(i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(i=1; i<=n; i++){ scanf("%d",&val[i]); } dfs1(1,1,1); fn = 0; dfs2(1,1); for(i=1; i<=n; i++){ Insert(w[i],val[i],1,fn,1); } int q; char s[10]; scanf("%d",&q); while(q--) { scanf("%s",s); int x,y; scanf("%d%d",&x,&y); if(s[0] == 'C'){ updata(w[x],y,1,fn,1); } else if(s[1] == 'S'){ printf("%d\n",Getsum(x,y)); } else { printf("%d\n",Getmax(x,y)); } } } }
相关文章推荐
- 【手把手教你全文检索】Lucene索引的【增、删、改、查】
- Android AppWidget控制手机上网APN接入点
- Mysql 中 if 的 用法
- Codeforces Round #339 (Div. 2) B. Gena's Code 水题
- poj3237 树链剖分 暴力
- hdu2548 两军交锋
- Linux驱动Platform总线模型
- LeetCode_HappyNumber_哈希表的使用
- 手把手教你全文检索 Apache Lucene初探
- 三格图片轮播
- ios 公司账号申请
- 网络发现打不开,每次点开启之后又变关闭
- 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)
- 多线程的基本概念
- git hook部署代码
- 数据结构优化连边
- Linux /UNIX 状态解释
- Java时间
- Codeforces round339 div2
- java推荐书籍及下载