题意:

给一棵树型数据结构

①支持修改边的权值      ②支持成段边权最值查询

树链剖分入门题、

树链剖分+线段树

用的notonlysuccess的线段树——不开结构体事先预处理的那种

我以前写的都是结构体的那种~

View Code

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <cstring>
  6
  7 //notonlysuccess版线段树-树链剖分
  8
  9 #define N 20010
 10
 11 using namespace std;
 12
 13 int d[N][3];
 14 int to[N<<1],next[N<<1];
 15 int mx[N];
 16 int root,tot,cnt,n,m,cas;
 17 int head[N],dep[N],wnum[N],fa[N],top[N],son[N],sz[N];
 18 //sz[x]树的大小   dep[x]深度    top[x] x所在重路径中深度最小的点    fa[x]父亲节点   son[x]重儿子   wnum[x] x与其父亲之间的边的编号
 19
 20 inline void add(int u,int v)
 21 {
 22     to[cnt]=v; next[cnt]=head[u]; head[u]=cnt++;
 23 }
 24
 25 inline void dfs(int x)//dfs求出fa[x],son[x],dep[x],sz[x]
 26 {
 27     sz[x]=1; son[x]=0;
 28     for(int i=head[x];~i;i=next[i])
 29         if(fa[x]!=to[i])
 30         {
 31             fa[to[i]]=x;
 32             dep[to[i]]=dep[x]+1;
 33             dfs(to[i]);
 34             if(sz[to[i]]>sz[son[x]]) son[x]=to[i];//重边
 35             sz[x]+=sz[to[i]];
 36         }
 37 }
 38
 39 inline void build(int x,int fx)//求出top[x],wnum[x](边的编号)
 40 {
 41     wnum[x]=++tot; top[x]=fx;
 42     if(son[x]!=0) build(son[x],top[x]);//保证重边边权相连
 43     for(int i=head[x];~i;i=next[i])
 44         if(to[i]!=son[x]&&to[i]!=fa[x]) build(to[i],to[i]);
 45 }
 46
 47 inline void updata(int x,int lt,int rt,int wn,int w)
 48 {
 49     if(wn>rt||wn<lt) return;
 50     if(lt==rt) {mx[x]=w; return;}
 51     int mid=(lt+rt)>>1;
 52     int ls=x<<1,rs=ls+1;
 53     updata(ls,lt,mid,wn,w);
 54     updata(rs,mid+1,rt,wn,w);
 55     mx[x]=max(mx[ls],mx[rs]);
 56 }
 57
 58 inline int maxlen(int x,int lt,int rt,int l,int r)//求边的编号在[l,r]之间的最大边权
 59 {
 60     if(l>rt||r<lt) return 0;
 61     if(l<=lt&&rt<=r) return mx[x];
 62     int mid=(lt+rt)>>1;
 63     int ls=x<<1,rs=ls+1;
 64     return max(maxlen(ls,lt,mid,l,r),maxlen(rs,mid+1,rt,l,r));
 65 }
 66
 67 inline int query(int x,int y)
 68 {
 69     int fx=top[x],fy=top[y],ans=0;
 70     while(fx!=fy)
 71     {
 72         if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
 73         ans=max(ans,maxlen(1,1,tot,wnum[fx],wnum[x]));
 74         x=fa[fx]; fx=top[x];
 75     }
 76     if(x==y) return ans;
 77     if(dep[x]>dep[y]) swap(x,y);
 78     return max(ans,maxlen(1,1,tot,wnum[son[x]],wnum[y]));
 79 }
 80
 81 inline void read()
 82 {
 83     scanf("%d",&n);
 84     root=(n+1)>>1;
 85     fa[root]=dep[root]=cnt=tot=0;
 86     memset(sz,0,sizeof sz);
 87     memset(head,-1,sizeof head);
 88     memset(mx,0,sizeof mx);
 89     for(int i=1;i<n;i++)
 90     {
 91         scanf("%d%d%d",&d[i][0],&d[i][1],&d[i][2]);
 92         add(d[i][0],d[i][1]);
 93         add(d[i][1],d[i][0]);
 94     }
 95     dfs(root);
 96     build(root,root);
 97     for(int i=1;i<n;i++)
 98     {
 99         if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]);
100         updata(1,1,tot,wnum[d[i][1]],d[i][2]);
101     }
102 }
103
104 inline void go()
105 {
106     char str[10]; int a,b;
107     while(true)
108     {
109         scanf("%s",str);
110         if(str[0]=='D') return;
111         scanf("%d%d",&a,&b);
112         if(str[0]=='Q') printf("%d\n",query(a,b));
113         else updata(1,1,tot,wnum[d[a][1]],b);
114     }
115 }
116
117 int main()
118 {
119     scanf("%d",&cas);
120     while(cas--) read(),go();
121     return 0;
122 } 

又写了一发,和之前风格完全不同。。

View Code

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <algorithm>
  6
  7 #define N 100000
  8 #define M 200000
  9 #define INF 1e9
 10
 11 using namespace std;
 12
 13 int head[N],next[M],to[M],len[M];
 14 int son[N],fa[N],dat[M],bh[M],pre[N],dep[N],sz[N],top[N];
 15 int q[N],mx[M<<2];
 16 int n,cnt,tot;
 17
 18 inline void add(int u,int v,int w)
 19 {
 20     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
 21 }
 22
 23 inline void init()
 24 {
 25     memset(son,-1,sizeof son);
 26     memset(fa,0,sizeof fa);
 27     memset(head,-1,sizeof head); cnt=0;
 28     tot=0;
 29 }
 30
 31 inline void prep()
 32 {
 33     int h=1,t=2,sta;
 34     q[1]=1; dep[1]=1;
 35     while(h<t)
 36     {
 37         sta=q[h++]; sz[sta]=1;
 38         for(int i=head[sta];~i;i=next[i])
 39             if(fa[sta]!=to[i])
 40             {
 41                 fa[to[i]]=sta;
 42                 dep[to[i]]=dep[sta]+1;
 43                 pre[to[i]]=len[i];
 44                 q[t++]=to[i];
 45             }
 46     }
 47     for(int j=t-1;j>=1;j--)
 48     {
 49         sta=q[j];
 50         for(int i=head[sta];~i;i=next[i])
 51             if(fa[sta]!=to[i])
 52             {
 53                 sz[sta]+=sz[to[i]];
 54                 if(son[sta]==-1||sz[to[i]]>sz[to[son[sta]]]) son[sta]=i;
 55             }
 56     }
 57     for(int i=1;i<t;i++)
 58     {
 59         sta=q[i];
 60         if(to[son[fa[sta]]]==sta) top[sta]=top[fa[sta]];
 61         else top[sta]=sta;
 62     }
 63 }
 64
 65 inline void rewrite()
 66 {
 67     for(int i=1;i<=n;i++)
 68         if(top[i]==i)
 69             for(int j=son[i];~j;j=son[to[j]])
 70             {
 71                 bh[(j>>1)+1]=++tot;
 72                 dat[tot]=len[i];
 73             }
 74 }
 75
 76 inline void pushup(int u)
 77 {
 78     mx[u]=max(mx[u<<1],mx[u<<1|1]);
 79 }
 80
 81 inline void build(int u,int L,int R)
 82 {
 83     if(L==R) {mx[u]=dat[L];return;}
 84     int MID=(L+R)>>1;
 85     build(u<<1,L,MID); build(u<<1|1,MID+1,R);
 86     pushup(u);
 87 }
 88
 89 inline void read()
 90 {
 91     init();
 92     scanf("%d",&n);
 93     for(int i=1,a,b,c;i<n;i++)
 94     {
 95         scanf("%d%d%d",&a,&b,&c);
 96         add(a,b,c); add(b,a,c);
 97     }
 98
 99     prep();
100     rewrite();
101     build(1,1,tot);
102 }
103
104 inline void updata(int u,int L,int R,int pos,int sp)
105 {
106     if(L==R) {mx[u]=sp;return;}
107     int MID=(L+R)>>1;
108     if(pos<=MID) updata(u<<1,L,MID,pos,sp);
109     else updata(u<<1|1,MID+1,R,pos,sp);
110     pushup(u);
111 }
112
113 inline int querymax(int u,int L,int R,int l,int r)
114 {
115     if(l<=L&&R<=r) return mx[u];
116     int MID=(L+R)>>1,res=-INF;
117     if(l<MID) res=max(res,querymax(u<<1,L,MID,l,r));
118     if(MID<r) res=max(res,querymax(u<<1|1,MID+1,R,l,r));
119     return res;
120 }
121
122 inline int getmax(int x,int y)
123 {
124     int res=-INF;
125     while(top[x]!=top[y])
126     {
127         if(dep[top[x]]<dep[top[y]]) swap(x,y);
128         res=max(res,querymax(1,1,tot,bh[top[x]],bh[x]));
129         res=max(res,pre[top[x]]);
130         x=fa[top[x]];
131     }
132     if(bh[x]>bh[y]) swap(x,y);
133     res=max(res,querymax(1,1,tot,bh[x],bh[y]));
134     return res;
135 }
136
137 inline void go()
138 {
139     char str[10];int a,b;
140     while(scanf("%s",str))
141     {
142         if(str[0]=='D') break;
143         scanf("%d%d",&a,&b);
144         if(str[0]=='C') updata(1,1,tot,bh[a],b);
145         else printf("%d\n",getmax(a,b));
146     }
147 }
148
149 int main()
150 {
151     int cas;scanf("%d",&cas);
152     while(cas--) read(),go();
153     return 0;
154 }

转载于:https://www.cnblogs.com/proverbs/archive/2013/01/02/2842572.html

SPOJ 375 query on a tree 树链剖分相关推荐

  1. SPOJ - QTREE Query on a tree(树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型: QUERY x y:询问点x-点y这条路径上的所有边权的最大值 CHANGE x y:将第x条边的权 ...

  2. HDU - 3804 Query on a tree(树链剖分+线段树+离线处理)

    题目链接:点击查看 题目大意:给出一棵树,每条边上都有一个权值,给出m个查询:a,b:问从点1到点a的唯一路径上,在边权小于等于b的边中选出边权最大的值输出,若没有符合条件的边则输出-1: 题目分析: ...

  3. SPOJ Query on a tree 树链剖分 边修改

    链接 提交链接 题解 对边的修改算到点上 只需要修改下面的地方 代码 #include<bits/stdc++.h> #define N 10010 #define INF 0x3f3f3 ...

  4. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  5. spoj 375 Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 题意: 给一颗树,每条边有一个权值.有两种操作: 1.修改某条边的值: 2.询问a.b两点路径上边权的最大值. 分析 ...

  6. spoj 375 Query on a tree

    题意:给一棵树,节点数不超过10000,有两个操作:1.询问a,b路径上最长的边长.2.把第a条边长度改为b. p.s.人生中第一个树链剖分,尼玛debug了好久好久我擦... 分析:轻重边路径剖分, ...

  7. POJ 3237.Tree -树链剖分(边权)(边值更新、路径边权最值、区间标记)贴个板子备忘...

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12247   Accepted: 3151 Descriptio ...

  8. CodeForces - 343D Water Tree(树链剖分+线段树)

    题目链接: 题目大意:给出一棵由n个点组成的树,初始时每个点的权值为0,接下来有m个操作,每个操作分为以下三种: 1 x:将包括节点x在内的所有子孙节点的权值都改为1 2 x:将包括节点x在内的所有父 ...

  9. 计蒜客 - Distance on the tree(树链剖分+离线处理+线段树)

    题目链接:点击查看 题目大意:给出一颗含有n个节点的树,每条边都有权值,现在给出m个询问,每次询问的格式为u,v,w,我们需要求出在路径u-v上,边权小于等于w的边的个数 题目分析:因为一开始不会主席 ...

最新文章

  1. spring集成 JedisCluster 连接 redis3.0 集群
  2. Linux mysql federated_MySQL的FEDERATED引擎实现类Oracle的DBlink
  3. Java魔法堂:初探MessageFormat.format和ChoiceFormat
  4. mac 用户 文件夹 权限_Mac视频播放软件推荐
  5. C语言——二分法查找一个数_数组
  6. Java复习第三天-静态方法
  7. linux部署python web_在linux上部署web环境
  8. asp.net下Response.ContentType类型汇总
  9. LibSvm使用说明和LibSvm源码解析
  10. 图形数据库 Neo4j(2) ----Java
  11. 学qt的都干什么工作_【板绘前景】学板绘可以干什么工作?学多久才可以工作?好学吗?...
  12. HashMap的实现原理、JDK1.7和JDK1.8的对比以及死锁问题
  13. 优卡仕广告一体机——商用显示设备专家
  14. 高斯-约当消元法(转)
  15. 回归预测分析(RANSAC、多项式回归、残差图、随机森林)
  16. 魔兽世界linux客户端,使用Wine在Linux下玩魔兽世界
  17. 初中数学结合计算机教学设计,初中数学教学设计中多媒体技术的运用
  18. 一文读懂谷歌I/O 新硬件、Android Q及多项功能升级
  19. linux图形界面介绍
  20. String intern驻足

热门文章

  1. 【物联网】QCA4010之SNTP协议
  2. Struts 2基础
  3. python3网络爬虫开发实战下载_【Python3网络爬虫开发实战】 1.1-Python3的安装
  4. java里的主线程和子线程以及finally不会执行的特殊情况
  5. python中items属性的用法
  6. jsp ajax三级联动,Spring MVC+JSP实现三级联动
  7. VC各种情况下的窗口句柄的获取
  8. pixhawk的姿态控制算法解读
  9. define宏定义和const定义之间的区别
  10. Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (括号配对,前缀和)