热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

poj3237--Tree树链剖分

题意:三种操作①修改第i条边的权值为val,②把u到v路径上的所有边的权值去相反数③求u到v路径上最大的边权线段树的区间更新还是不熟练,,一直搞不对调试了好久还是没对,最后还是看的kuang

题意:三种操作 ①修改第i条边的权值为val,②把u到v路径上的所有边的权值 去相反数③求u 到v路径上最大的边权

线段树的区间更新还是不熟练,,一直搞不对调试了好久还是没对,最后还是看的kuangbin的代码。

 

  1 #include 
  2 #include 
  3 #include 
  4 #include 
  5 #include 
  6 using namespace std;
  7 typedef unsigned long long ull;
  8 typedef long long ll;
  9 const int inf = 0x3f3f3f3f;
 10 const double eps = 1e-8;
 11 const int maxn = 1e5+10;
 12 struct
 13 {
 14     int to,next;
 15 }e[maxn<<1];
 16 int head[maxn],edge;
 17 void add(int x,int y)
 18 {
 19     e[edge].to = y;
 20     e[edge].next = head[x];
 21     head[x] = edge++;
 22 }
 23 int son[maxn],fa[maxn],siz[maxn],dep[maxn];
 24 void dfs(int root)
 25 {
 26     siz[root] = 1;
 27     son[root] = 0;
 28     for (int i = head[root]; i > 0; i = e[i].next)
 29     {
 30         if (fa[root] != e[i].to)
 31         {
 32             dep[e[i].to] = dep[root] + 1;
 33             fa[e[i].to] = root;
 34             dfs(e[i].to);
 35             if (siz[e[i].to] > siz[son[root]])
 36                 son[root] = e[i].to;
 37             siz[root] += siz[e[i].to];
 38         }
 39     }
 40 }
 41 int tot,top[maxn],li[maxn<<2],pos[maxn];
 42 void build(int root,int father)
 43 {
 44     top[root] = father;
 45     pos[root] = tot;
 46     li[tot++] = root;
 47     if (son[root] > 0)
 48         build(son[root],top[root]);
 49     for (int i = head[root]; i > 0; i = e[i].next)
 50         if (fa[root] != e[i].to && son[root] != e[i].to)
 51             build(e[i].to,e[i].to);
 52 }
 53 
 54 int minv[maxn<<2],maxv[maxn<<2], tt[maxn],lazy[maxn<<2];
 55 void build_Segtree(int l,int r,int o)
 56 {
 57     lazy[o] = 0;
 58     if (l == r)
 59     {
 60         minv[o] = tt[li[l]];
 61         maxv[o] =tt[li[l]];
 62         return;
 63     }
 64     int mid = (l + r) >> 1;
 65     build_Segtree(l,mid,o<<1);
 66     build_Segtree(mid+1,r,o<<1|1);
 67     minv[o] = min(minv[o<<1],minv[o<<1|1]);
 68     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);
 69 }
 70 char op[10];
 71 int val;
 72 inline void push_down(int l,int r,int o)
 73 {
 74     if (lazy[o]&&l!=r)
 75     {
 76         maxv[o<<1] = -maxv[o<<1];
 77         minv[o<<1] = -minv[o<<1];
 78         maxv[o<<1|1] = -maxv[o<<1|1];
 79         minv[o<<1|1] = -minv[o<<1|1];
 80         swap(maxv[o<<1],minv[o<<1]);
 81         swap(maxv[o<<1|1],minv[o<<1|1]);
 82         lazy[o<<1] ^= 1;
 83         lazy[o<<1|1] ^= 1;
 84         lazy[o] = 0;
 85     }
 86 }
 87 void update(int l,int r,int o,int ua,int ub)
 88 {
 89     if (ua <= l && ub >= r)
 90     {
 91         if (op[0] == 'N')
 92         {
 93             maxv[o] = -maxv[o];
 94             minv[o] = -minv[o];
 95             swap(maxv[o],minv[o]);
 96             lazy[o] ^= 1;
 97         }
 98         if (op[0] == 'C')
 99             minv[o] = maxv[o]  = val,lazy[o] = 0;
100         return;
101     }
102     //if (op[0] == 'N')
103     push_down(l,r,o);
104     int mid = (l + r) >> 1;
105     if (ua <= mid)
106         update(l,mid,o<<1,ua,ub);
107     if (ub > mid)
108         update(mid+1,r,o<<1|1,ua,ub);
109     minv[o] = min(minv[o<<1],minv[o<<1|1]);
110     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);
111 }
112 
113 int query(int l,int r,int o,int ua,int ub)
114 {
115     if (ua <= l && ub >= r)
116         return maxv[o];
117     int mid = (l + r) >> 1;
118     push_down(l,r,o);
119     int t1 = -inf,t2 = -inf;
120     if (ua <= mid)
121         t1 = query(l,mid,o<<1,ua,ub);
122     if (ub > mid)
123         t2 = query(mid+1,r,o<<1|1,ua,ub);
124     minv[o] = min(minv[o<<1],minv[o<<1|1]);
125     maxv[o] = max(maxv[o<<1],maxv[o<<1|1]);
126     return max(t1,t2);
127 }
128 
129 int get_max(int ua,int ub)
130 {
131     int f1 = top[ua];
132     int f2 = top[ub];
133     int tmp = -inf;
134     while (f1 != f2)
135     {
136         if (dep[f1] < dep[f2])
137             swap(ua,ub),swap(f1,f2);
138         tmp = max(tmp,query(1,tot,1,pos[f1],pos[ua]));
139         ua = fa[f1];
140         f1 = top[ua];
141     }
142     if (ua == ub)
143         return tmp;
144     if (dep[ua]  > dep[ub])
145         swap(ua,ub);
146     return tmp = max(tmp,query(1,tot,1,pos[son[ua]],pos[ub]));
147 }
148 void get_negate(int ua,int ub)
149 {
150     int f1 = top[ua];
151     int f2 = top[ub];
152     while (f1 != f2)
153     {
154         if (dep[f1] < dep[f2])
155             swap(ua,ub),swap(f1,f2);
156         update(1,tot,1,pos[f1],pos[ua]);
157         ua = fa[f1];
158         f1 = top[ua];
159     }
160     if (dep[ua] > dep[ub])
161         swap(ua,ub);
162     if (ua == ub)
163         return;
164     update(1,tot,1,pos[son[ua]],pos[ub]);
165 }
166 
167 int d[maxn][3];
168 void init()
169 {
170     int root,n;
171     scanf ("%d",&n);
172     root = (n + 1) >> 1;
173     edge = tot = 1;
174     memset(siz,0,sizeof(siz));
175     memset(head,0,sizeof(head));
176     fa[root] = dep[root] = 0;
177     for (int i = 1; i )
178     {
179         scanf ("%d%d%d",&d[i][0],&d[i][1],&d[i][2]);
180         add(d[i][1],d[i][0]);
181         add(d[i][0],d[i][1]);
182     }
183     dfs(root);
184     build(root,root);
185     build_Segtree(1,tot,1);
186     op[0] = 'C';
187     for (int i = 1; i )
188     {
189         if (dep[d[i][0]] 1]])
190             swap(d[i][0],d[i][1]);
191         tt[d[i][0]] = val = d[i][2];
192         update(1,tot,1,pos[d[i][0]],pos[d[i][0]]);
193     }
194 }
195 int main(void)
196 {
197     freopen("in.txt","r",stdin);
198     int t;
199     scanf ("%d",&t);
200     while (t--)
201     {
202         init();
203         while (scanf ("%s",op),op[0] != 'D')
204         {
205             int x,y;
206             scanf ("%d%d",&x,&y);
207             if (op[0] == 'Q'&&x!=y)
208                 printf("%d\n",get_max(x,y));
209             if (op[0] == 'Q' && x == y)
210                 printf("0\n");
211             if (op[0] == 'C')
212             {
213                 val = y;
214                 update(1,tot,1,pos[d[x][0]],pos[d[x][0]]);
215             }
216             if (op[0] == 'N'&&x!=y)
217                 get_negate(x,y);
218         }
219     }
220     return 0;
221 }
222 
223 
224 /*
225 1
226 11
227 2 1 1
228 2 4 2
229 2 3 3
230 1 5 4
231 3 6 5
232 3 7 6
233 7 8 7
234 4 9 8
235 9 10 9
236 10 11 10
237 N 2 10
238 Query 4 10
239 DONE
240 
241 */

 


推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
author-avatar
嗯哼
很清新
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有