SPOJ QTREE 树链剖分
2015-08-27 17:32
453 查看
#include <cstdio> #include <cstring> #include <iostream> #include <set> #include <queue> #include <algorithm> #include <cmath> #include <vector> using namespace std; #define N 10010 #define ls o<<1 #define rs o<<1|1 #define define_m int m=(l+r)>>1 int maxn[N<<2] , dis ; struct Edge{ int x,y,d; Edge(int x=0 , int y=0 , int d=0):x(x),y(y),d(d){} }; vector<Edge> v ; int fa , son , sz , top , dep , id , k; int n , st , en , d , val; char str[20]; void dfs(int u , int f , int d) { fa[u] = f; sz[u] = 1 , dep[u]=d , son[u]=0; int len = v[u].size(); int maxn = 0; for(int i=0 ; i<len ; i++){ int to=v[u][i].y; if(to==f) continue; dfs(to,u,d+1); sz[u]+=sz[to]; if(sz[to]>maxn){ son[u]=to; maxn = sz[to]; } } } void dfs1(int u , int f , int head) { int l=v[u].size(); top[u] = head; if(son[u]){ id[son[u]] = ++k; dfs1(son[u] , u , head); } for(int i=0 ; i<l ; i++){ int to = v[u][i].y; if(to==f || to==son[u]) continue; id[to] = ++k; dfs1(to , u , to); } } void push_up(int o) { maxn[o] = max(maxn[ls] , maxn[rs]); } void build(int o , int l , int r) { if(l==r){ maxn[o] = dis[l]; return ; } define_m; build(ls , l , m); build(rs , m+1 , r); push_up(o); } void update(int o , int l , int r , int pos, int v) { if(l==r && l==pos){ maxn[o] = v; return; } define_m; if(m>=pos) update(ls , l , m , pos , v); else update(rs , m+1 , r , pos , v); push_up(o); } int query(int o , int l , int r , int s , int t) { // cout<<"query: "<<o<<" "<<l<<" "<<r<<" "<<s<<" "<<t<<endl; if(l>=s && r<=t){ return maxn[o]; } int ans = 0; define_m; if(m>=s) ans = max(ans , query(ls , l , m , s , t)); if(m<t) ans= max(ans , query(rs , m+1 , r , s , t)); return ans; } int CalPath(int u , int v) { int top1=top[u] , top2=top[v]; int ans = 0; while(top1 != top2){ if(dep[top1]<dep[top2]){ swap(top1 , top2); swap(u , v); } ans = max(ans , query(1 , 1 , k , id[top1] , id[u])); u=fa[top1]; top1=top[u]; } if(u!=v){ if(dep[u]<dep[v]){ swap(u,v); } ans=max(ans,query(1,1,k,id[son[v]],id[u])); // cout<<"in: "<<id[u]<<" "<<id[son[v]]<<endl; // cout<<"u: "<<u<<" v: "<<v<<" "<<ans<<endl; } return ans; } int main() { // freopen("a.in" , "r" , stdin); int T; scanf("%d" , &T); while(T--) { scanf("%d" , &n); for(int i=1 ; i<=n ; i++) v[i].clear(); for(int i=1 ; i<n ; i++){ scanf("%d%d%d" , &st[i] , &en[i] , &d[i]); v[st[i]].push_back(Edge(st[i],en[i],d[i])); v[en[i]].push_back(Edge(en[i],st[i],d[i])); } k=0; dfs(1,0,1); dfs1(1,0,1); for(int i=1 ; i<n ; i++){ int ID; if(st[i] != fa[en[i]]) ID = id[st[i]]; else ID = id[en[i]]; // cout<<"ID: "<<ID<<endl; dis[ID] = d[i]; } /* for(int i=1 ; i<=n ; i++){ cout<<fa[i]<<" "<<son[i]<<" "<<dep[i]<<" "<<sz[i]<<" "<<top[i]<<" "<<id[i]<<endl; if(i<n) cout<<"i: "<<dis[i]<<endl; }*/ build(1,1,k); // cout<<"sum: "<<sum[1]<<" "<<sum[2]<<" "<<sum[3]<<endl; while(scanf("%s" , str) && str[0]!='D'){ int t1 , t2; scanf("%d%d" , &t1 , &t2); if(str[0] == 'C'){ int ID; if(st[t1] != fa[en[t1]]) ID = id[st[t1]]; else ID = id[en[t1]]; // cout<<"ID: "<<ID<<endl; update(1,1,k,ID,t2); } else{ int ans = CalPath(t1,t2); printf("%d\n" , ans); } } } return 0; }
相关文章推荐
- Ubuntu下QT程序中编译时出现speex/speex.h: No such file or directory
- Qt 导出EXCEL文件
- Qt中rotate和trabslate的使用
- Qt安装配置
- emqttd(Erlang开发MQTT消息服务器) V0.10.0 免费版怎么样
- Qt 对话框显示控制按钮
- Qt+MSVC2013 使用QtCreator中文乱码问题
- Qt调用dll的步骤
- Qt入门学习——Qt Creator的使用
- QT之QListWidget与QListWidgetItem
- QT事件(2)
- Qt 之 运行Qt Creator出现cannot find -lGL的问题的两种解决
- Ubuntu下Qt4.8.6生成的界面中文无法显示的问题
- Qt QString的arg()方法的使用
- Qt Designer中的layoutstretch属性
- vs2012+qt5.2.0环境搭建/vs2013 + qt5.3.2 环境搭建
- 零基础学Qt 4编程实例之Qt 样式表的应用
- Qt知识点、疑难杂症的治疗
- Qt中的多线程技术
- QT---qtextedit中的光标问题