LCT spoj 375 树链剖分
来源:互联网 发布:洛阳seo牛广 编辑:程序博客网 时间:2024/05/08 05:18
树链剖分
才完全看懂树链剖分 我好弱啊
同学们都已经烂熟于心了 然而我却。。。
心得
先推荐大家去看 点击打开链接http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html
这个博客讲的特别的好
树链剖分 就是 两遍dfs 把这棵树的各种路都铺好 top fa son(重儿子 好势利。。) 等等的
在第二遍dfs 中 还有一个是 w数组 (signaficant) 这个数组 用来记录x作为儿子连得是第几条边 (注意是作为儿子 !因为 作为父亲可能连了好几条边)
读入优化 写的学习了
最最重要的是 也是为什么这个写法比比的写法要短的原因 : 线段树
他缩减了线段树因为在这个题目里面 根本就用不到 正常的build .l .r .val 都用不到 所以在第二遍dfs 的时候 都可以初始化好
上自己的代码
#include <cstdio>#include <algorithm>#include <iostream>#include <string.h>using namespace std;const int maxn = 10010;int tr[maxn];int zzz, n, z, root, a, b, c;int d[maxn][3];int head[maxn], dep[maxn], w[maxn], fa[maxn], top[maxn], son[maxn], siz[maxn];char ch[10];struct edge{ int to,next;}e[maxn*2];int cnt;void insert (int u, int v){ e[++cnt].to=v; e[cnt].next = head[u]; head[u]=cnt;}void dfs1(int x){ siz[x]=1,son[x]=0; for(int i=head[x];i;i=e[i].next) { if(e[i].to!=fa[x]) { fa[e[i].to]=x; dep[e[i].to]=dep[x]+1; dfs1(e[i].to); siz[x]+=siz[e[i].to]; if(siz[e[i].to]>siz[son[x]]) son[x]=e[i].to; } }}void build_tree(int x,int tp){ w[x]=++z; top[x]=tp; if(son[x]) build_tree(son[x],top[x]); for(int i=head[x];i;i=e[i].next) { if(e[i].to!=son[x]&&e[i].to!=fa[x]) { build_tree(e[i].to,e[i].to); } }}void updata(int ro,int lt,int rt,int k,int val){ if(k>rt||k<lt) return ; if(lt==rt) tr[ro]=val; else { int mid=(lt+rt)>>1; updata(ro<<1,lt,mid,k,val); updata(ro<<1|1,mid+1,rt,k,val); tr[ro]=max(tr[ro<<1],tr[ro<<1|1]); } }int q(int ro,int lt,int rt,int l,int r){ if(l>rt||r<lt) return 0; if(r<=rt&&l>=lt) return tr[ro]; int mid=(lt+rt)>>1; return max(q(ro<<1,lt,mid,l,r),q(ro<<1|1,mid+1,rt,l,r)); }inline int find(int a,int b){ int f1=top[a],f2=top[b],temp=0; while(f1!=f2) { if(dep[f1]<dep[f2]) swap(f1,f2),swap(a,b); temp=max(temp,q(1,1,z,w[f1],w[a])); a=fa[f1]; f1=top[a]; } if(a==b) return temp; if(dep[a]>dep[b]) swap(a,b); return max(temp,q(1,1,z,w[son[a]],w[b]));}void init(){ scanf("%d",&n); root=(n+1)>>1; fa[root]=z=dep[root]=0; memset(head,0,sizeof(head)); memset(tr,0,sizeof(tr)); memset(siz,0,sizeof(siz)); for(int i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); d[i][0]=a; d[i][1]=b; d[i][2]=c; insert(a,b); insert(b,a); } dfs1(root); build_tree (root,root); for(int i=1;i<n;i++) { if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); updata(1,1,z,w[d[i][1]],d[i][2]); }}inline void rd(){ ch[0]=' '; while(ch[0]<'C'||ch[0]>'Q') scanf("%s",&ch);}void work(){ for(rd();ch[0]!='D';rd()) { scanf("%d%d",&a,&b); if(ch[0]=='Q') { printf("%d",find(a,b)); } else { updata(1,1,z,w[d[a][1]],b); } }}int main(){ for(scanf("%d",&zzz);zzz>0;zzz--) { init(); work(); } return 0;}
写的很烂 毕竟我是弱弱
By LT
0 0
- LCT spoj 375 树链剖分
- SPOJ 375 LCT学习
- spoj 375 QTREE - Query on a tree 树链剖分 LCT 动态树
- SPOJ GSS7 && Vijos1620 【LCT】
- spoj 4155 (LCT)
- SPOJ QTREE LCT
- 【SPOJ】 4155. OTOCI LCT
- SPOJ QTREE lct
- SPOJ QTREE2 lct
- SPOJ QTREE3 lct
- SPOJ QTREE5 lct
- SPOJ QTREE4 lct
- SPOJ QTREE6 lct
- SPOJ QTREE7 lct
- spoj-QTREE3 LCT
- 动态树LCT||树链剖分+线段树(SPOJ QTREE3 - Query on a tree again!)
- SPOJ Query on a tree——(树链剖分和LCT动态树)
- SPOJ QTREE Query on a tree (lct)
- ios中循环引用问题
- scrapyd部署
- 542.01 Matrix
- cas4.2.x 添加验证码
- HDU 1300 Pearls 动态规划 dp
- LCT spoj 375 树链剖分
- JSON 与 JS 对象的关系
- RabbitMQ服务安装配置
- php 四种基本排序算法
- 京东实习笔试——通过考试
- 网站页面每天都有收录,为什么还是没有排名?
- 分类之性能评估指标ROC&AUC
- Mac下Hive安装和使用
- webpack 图片的处理