4127: Abs

Time Limit: 40 Sec  Memory Limit: 256 MB
Submit: 667  Solved: 225
[Submit][Status][Discuss]

Description

 给定一棵树,设计数据结构支持以下操作1 u v d  表示将路径 (u,v) 加d2 u v  表示询问路径 (u,v) 上点权绝对值的和

Input

第一行两个整数n和m,表示结点个数和操作数
接下来一行n个整数a_i,表示点i的权值
接下来n-1行,每行两个整数u,v表示存在一条(u,v)的边
接下来m行,每行一个操作,输入格式见题目描述

Output

对于每个询问输出答案

Sample Input

4 4
-4 1 5 -2
1 2
2 3
3 4
2 1 3
1 1 4 3
2 1 3
2 3 4

Sample Output

10
13
9

写完之后BUG一段,TLE+WA+RE了快50发

线段树节点存三个值:最大的负数,负数的个数,当前绝对值大小

叶子结点多存一个实际值

区间修改查询就直接区间操作

如果当前修改的那个区间全是正数或者最大的负数+当前值后还是负数,就懒惰

否则暴力修改

因为每次加的值都是正数,所以每个数改变符号只会发生1次,暴力操作只会进行n次,复杂度额外的O(nlogn)

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct
{int to;int next;
}Road;
Road G[200005];
typedef struct Tree
{LL sum, rit;int mat, bet;Tree operator + (const Tree &b) const{Tree now;now.sum = sum+b.sum;now.mat = mat+b.mat;if(bet>=0)now.bet = b.bet;else if(b.bet>=0)now.bet = bet;elsenow.bet = max(bet, b.bet);return now;}
}Tree;
Tree tre[844444];
int head[150005], val[150005], fa[150005], son[150005], siz[150005], dep[150005];
int n, xt, cnt, rak[150005], id[150005], top[150005];
LL temp[844444];
void Add(LL u, LL v)
{cnt++;G[cnt].next = head[u];head[u] = cnt;G[cnt].to = v;
}
void Sech1(int u, int p)
{int i, v;fa[u] = p;dep[u] = dep[p]+1;for(i=head[u];i!=0;i=G[i].next){v = G[i].to;if(v==p)continue;Sech1(v, u);siz[u] += siz[v]+1;if(son[u]==0 || siz[v]>siz[son[u]])son[u] = v;}
}
void Sech2(int u, int p)
{int i, v;top[u] = p;rak[u] = ++xt, id[xt] = u;if(son[u]==0)return;Sech2(son[u], p);for(i=head[u];i!=0;i=G[i].next){v = G[i].to;if(son[u]==v || fa[u]==v)continue;Sech2(v, v);}
}
void Lazy(int l, int r, int x);
LL Query(int l, int r, int x, int a, int b);
void Create(int l, int r, int x);
void Update(int l, int r, int x, int a, int b, int c);
void Update_Tre(int x, int y, int d)
{int p1, p2;p1 = top[x], p2 = top[y];while(p1!=p2){if(dep[p1]<dep[p2])swap(x, y), swap(p1, p2);Update(1, n, 1, rak[p1], rak[x], d);x = fa[p1], p1 = top[x];}if(dep[x]>dep[y])swap(x, y);Update(1, n, 1, rak[x], rak[y], d);
}
LL Query_Tre(int x, int y)
{LL sum = 0;int p1, p2;p1 = top[x], p2 = top[y];while(p1!=p2){if(dep[p1]<dep[p2])swap(x, y), swap(p1, p2);sum += Query(1, n, 1, rak[p1], rak[x]);x = fa[p1], p1 = top[x];}if(dep[x]>dep[y])swap(x, y);sum += Query(1, n, 1, rak[x], rak[y]);return sum;
}int main(void)
{int m, i, x, y, opt, d;//freopen("in.txt", "r", stdin);scanf("%d%d", &n, &m);for(i=1;i<=n;i++)scanf("%d", &val[i]);for(i=1;i<=n-1;i++){scanf("%d%d", &x, &y);Add(x, y);Add(y, x);}Sech1(1, -1);Sech2(1, 1);Create(1, n, 1);while(m--){scanf("%d%d%d", &opt, &x, &y);if(opt==1){scanf("%d", &d);Update_Tre(x, y, d);}elseprintf("%lld\n", Query_Tre(x, y));}return 0;
}void Create(int l, int r, int x)
{int m;if(l==r){tre[x].rit = val[id[r]];tre[x].sum = abs(tre[x].rit);tre[x].bet = tre[x].rit;if(tre[x].rit<0)tre[x].mat = 1;elsetre[x].mat = 0;return;}m = (l+r)/2;Create(l, m, x*2);Create(m+1, r, x*2+1);tre[x] = tre[x*2]+tre[x*2+1];
}
void Update(int l, int r, int x, int a, int b, int c)
{int m;if(l==r){tre[x].rit += c;tre[x].sum = abs(tre[x].rit);tre[x].bet = tre[x].rit;if(tre[x].rit<0)tre[x].mat = 1;elsetre[x].mat = 0;return;}if(temp[x])Lazy(l, r, x);if(l>=a && r<=b && (tre[x].mat==0 || tre[x].bet+c<0)){tre[x].bet += c;tre[x].sum += (LL)(r-l+1-2*tre[x].mat)*c;temp[x] += c;return;}m = (l+r)/2;if(a<=m)Update(l, m, x*2, a, b, c);if(b>=m+1)Update(m+1, r, x*2+1, a, b, c);tre[x] = tre[x*2]+tre[x*2+1];
}
LL Query(int l, int r, int x, int a, int b)
{int m;LL sum = 0;if(l>=a && r<=b)return tre[x].sum;if(temp[x])Lazy(l, r, x);m = (l+r)/2;if(a<=m)sum += Query(l, m, x*2, a, b);if(b>=m+1)sum += Query(m+1, r, x*2+1, a, b);return sum;
}
void Lazy(int l, int r, int x)
{int m;m = (l+r)/2;tre[x*2].bet += temp[x];tre[x*2+1].bet += temp[x];tre[x*2].sum += (m-l+1-2*tre[x*2].mat)*temp[x];tre[x*2+1].sum += (r-m-2*tre[x*2+1].mat)*temp[x];if(l==m)tre[x*2].rit += (m-l+1)*temp[x];if(m+1==r)tre[x*2+1].rit += (r-m)*temp[x];if(l<m)temp[x*2] += temp[x];if(r>m+1)temp[x*2+1] += temp[x];temp[x] = 0;
}
/*
5 100
-2 -1 0 1 2
1 2 2 3 3 4 4 5
1 1 5 2
2 1 5
*/

bzoj 4127: Abs(树链剖分+线段树)相关推荐

  1. BZOJ4127Abs——树链剖分+线段树

    题目描述 给定一棵树,设计数据结构支持以下操作 1 u v d 表示将路径 (u,v) 加d 2 u v 表示询问路径 (u,v) 上点权绝对值的和 输入 第一行两个整数n和m,表示结点个数和操作数 ...

  2. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1153  Solved: 421 [Submit][Sta ...

  3. BZOJ3862Little Devil I——树链剖分+线段树

    题目大意: 给一棵树,每条边可能是黑色或白色(起始都是白色),有三种操作: 1.将u到v路径上所有边颜色翻转(黑->白,白->黑) 2.将只有一个点在u到v路径上的边颜色翻转 3.查询u到 ...

  4. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一张 n 个点 m 条边组成的带权无向图,现在对于每条边来说,确定一下其分类: 一定是最小生成树上的边 可能是最小生成树上的边 一定不是最小生成树的边 题目分析:两种 ...

  5. CodeForces - 609E Minimum spanning tree for each edge(最小生成树+树链剖分+线段树/树上倍增)

    题目链接:点击查看 题目大意:给出一张 n 个点和 m 条边组成的无向图,现在询问包含每一条边的最小生成树 题目分析:考虑求解次小生成树的思路: 求出最小生成树 ans 枚举每一条非树边 ( u , ...

  6. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...

  7. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  8. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  9. BZOJ2325[ZJOI2011]道馆之战——树链剖分+线段树

    题目描述 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中 的每一个冰块都只能经过一次.当一个冰地上的所有冰块都被经过之后,到下一个冰地的楼梯才 ...

  10. YbtOJ-染色计划【树链剖分,线段树,tarjan】

    正题 题目大意 给出nnn个点的一棵树,每个点有个颜色aia_iai​,你每次可以选择一个颜色全部变成另一个颜色. 求最少多少次操作可以把一种颜色变成一个完整的连通块. 1≤k≤n≤2×1051\le ...

最新文章

  1. Python的零基础超详细讲解(第十二天)-Python函数及使用
  2. 在 Element-UI 的 Table 组件上添加列拖拽效果
  3. React - S1
  4. 数塔(HDU-2084)
  5. 分享小知识:善用Group By排序
  6. 在有网络还是比较好解决软件上的问题
  7. 序列化和反序列化(七)——Java对象的网络传输(二)
  8. VUE实现市、区二级联动
  9. 如何学习计算机思维,刘康平:为什么我们每个人都应该学习计算思维?
  10. 技术解读:Dragonfly 基于 P2P 的智能镜像加速系统
  11. 示波器X-Y模式显示利萨如(李沙育)与DIY图像
  12. 收藏一个Ping的小工具类,可用于网络中检测目的设备是否在线
  13. 抖音上热门?这几个一定要记住
  14. Java开发工程师的一点职业发展规划
  15. struct timeval
  16. (已解决)video标签在ios端默认全屏播放(h5开发)
  17. 【231】判断是否是2的次幂--位运算相关
  18. GWAS:mtag (Multi-Trait Analysis of GWAS) 分析
  19. 二叉树 | 20 周总结
  20. dotnet core 也能协调分布式事务啦!

热门文章

  1. 线上python课程一般多少钱-python培训班一般多少钱?一篇文章告诉你
  2. python和java选择哪个-python和Java选择哪一个?
  3. python是干什么用的-python中upper是做什么用的
  4. 自学python好找工作么-学习python后好找工作吗
  5. SpringSecurity系列(五) Spring Security 权限设计
  6. unity 导入gltf_基于gltf的GPU蒙皮动画(一)
  7. [Vue warn]: Error in render: TypeError: _self.$scopedSlots.default is not a function 错误解决
  8. 【java笔记】序列化和反序列化
  9. 【java笔记】线程状态
  10. html ts 播放,vue文件拆分为html + ts + css