水题,只是坑点多,\(tag\)为\(0\)时可能也要\(pushdown\),所以要\(bool\)标记是否需要。最后树链剖分询问时注意线段有向!!!

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#define R(a,b,c) for(register int a = (b); a <= (c); ++a)
#define nR(a,b,c) for(register int a = (b); a >= (c); --a)
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define MP make_pair
#ifdef QWQ
#define D_e_Line printf("\n------\n")
#define D_e(x) cerr << (#x) << " " << x << endl
#define C_e(x) cout << (#x) << " " << x << endl
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#define Pause() system("pause")
#include <cassert>
#define PASS fprintf(stderr, "Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#else
#define D_e_Line
#define D_e(x)
#define C_e(x)
#define FileOpen()
#define FileSave()
#define Pause()
#define PASS
#endif
using namespace std;
struct FastIO {
template<typename ATP> inline FastIO& operator >> (ATP &x) {
x = 0; int sign = 1; char c;
for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') sign = -1;
while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
if(sign == -1) x = -x;
return *this;
}
} io;
template<typename ATP> inline ATP Max(ATP x, ATP y) {
return x > y ? x : y;
}
template<typename ATP> inline ATP Min(ATP x, ATP y) {
return x < y ? x : y;
}
template<typename ATP> inline ATP Abs(ATP x) {
return x < 0 ? -x : x;
}
#include <vector>
const int N = 2e5 + 7;
struct Edge {
int nxt, pre;
} e[N << 1];
int head[N], cntEdge;
inline void add(int u, int v) {
e[++cntEdge] = (Edge){ head[u], v}, head[u] = cntEdge;
}
int fa[N], son[N], siz[N], dep[N], dfn[N], dfnIdx, top[N], rnk[N], val[N], n;
void DFS_First(int u, int father) {
dep[u] = dep[father] + 1, fa[u] = father, siz[u] = 1;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(v == father) continue;
DFS_First(v, u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
void DFS_Second(int u, int Tp) {
top[u] = Tp, dfn[u] = ++dfnIdx, rnk[dfnIdx] = u;
if(!son[u]) return;
DFS_Second(son[u], Tp);
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(v != fa[u] && v != son[u]) DFS_Second(v, v);
}
}
struct Seg {
int sum, val, pre, suf, tag;
bool flag;
Seg() {sum = val = pre = suf = tag = flag = 0;}
Seg operator + (const Seg &b) const {
Seg c;
c.sum = sum + b.sum;
c.val = Max(Max(val, b.val), suf + b.pre);
c.pre = Max(pre, sum + b.pre);
c.suf = Max(b.suf, b.sum + suf);
return c;
}
} t[N << 2];
#define ls rt << 1
#define rs rt << 1 | 1
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
inline void Pushup(int &rt) {
t[rt] = t[ls] + t[rs];
}
inline void Pushdown(int &rt, int l, int mid, int r) {
t[ls].sum = (mid - l + 1) * t[rt].tag;
t[rs].sum = (r - mid) * t[rt].tag;
t[ls].pre = t[ls].val = t[ls].suf = Max(t[ls].sum, 0);
t[rs].pre = t[rs].val = t[rs].suf = Max(t[rs].sum, 0);
t[ls].flag = t[rs].flag = true;
t[ls].tag = t[rs].tag = t[rt].tag;
t[rt].tag = 0;
t[rt].flag = false;
}
void Build(int rt, int l, int r) {
if(l == r){
t[rt].sum = val[rnk[l]];
t[rt].val = t[rt].pre = t[rt].suf = Max(t[rt].sum, 0);
return;
}
int mid = (l + r) >> 1;
Build(lson), Build(rson);
Pushup(rt);
}
void Updata(int rt, int l, int r, int L, int R, int w) {
if(L <= l && r <= R){
t[rt].sum = (r - l + 1) * w;
t[rt].pre = t[rt].suf = t[rt].val = Max(t[rt].sum, 0);
t[rt].tag = w;
t[rt].flag = true;
return;
}
int mid = (l + r) >> 1;
if(t[rt].flag) Pushdown(rt, l, mid, r);
if(L <= mid) Updata(lson, L, R, w);
if(R > mid) Updata(rson, L, R, w);
Pushup(rt);
}
Seg Query(int rt, int l, int r, int L, int R) {
if(L <= l && r <= R) return t[rt];
int mid = (l + r) >> 1;
if(t[rt].flag) Pushdown(rt, l, mid, r);
Seg s;
if(L <= mid) s = Query(lson, L, R);
if(R > mid) s = s + Query(rson, L, R);
return s;
}
inline void Updata(int x, int y, int w) {
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) Swap(x, y);
Updata(1, 1, n, dfn[top[x]], dfn[x], w);
x = fa[top[x]];
}
if(dep[x] < dep[y]) Swap(x, y);
Updata(1, 1, n, dfn[y], dfn[x], w);
}
//inline int Query(int x, int y) {
// Seg s;
// while(top[x] != top[y]){
// if(dep[top[x]] < dep[top[y]]) Swap(x, y);
// s = s + Query(1, 1, n, dfn[top[x]], dfn[x]);
// x = fa[top[x]];
// }
// if(dep[x] < dep[y]) Swap(x, y);
// Swap(s.suf, s.pre);
// return (s + Query(1, 1, n, dfn[y], dfn[x])).val;
//}
inline int Query(int x, int y) {
Seg L, R;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]){
R = Query(1, 1, n, dfn[top[y]], dfn[y]) + R;
y = fa[top[y]];
}
else{
L = Query(1, 1, n, dfn[top[x]], dfn[x]) + L;
x = fa[top[x]];
}
}
if(dep[x] > dep[y]){
L = Query(1, 1, n, dfn[y], dfn[x]) + L;
}
else{
R = Query(1, 1, n, dfn[x], dfn[y]) + R;
}
Swap(L.pre, L.suf);
return (L + R).val;
}
int main() {
//FileOpen();
//FileSave();
io >> n;
R(i,1,n) io >> val[i];
R(i,2,n){
int u, v;
io >> u >> v;
add(u, v);
add(v, u);
}
DFS_First(1, 0);
DFS_Second(1, 1);
Build(1, 1, n);
int m;
io >> m;
while(m--){
int opt, l, r, w;
io >> opt >> l >> r;
if(opt == 1){
printf("%d\n", Query(l, r));
}
else{
io >> w;
Updata(l, r, w);
}
} return 0;
}
/*
13
9 4 12 18 19 1 11 18 16 5 1 10 9 2 1
3 1
4 1
5 1
6 4
7 3
8 3
9 3
10 8
11 9
12 10
13 10
5
2 1 10 10
2 7 13 6
1 5 9
1 4 10
1 9 10
*/

SP6779 GSS7 - Can you answer these queries VII(线段树,树链剖分)的更多相关文章

  1. SP6779 GSS7 - Can you answer these queries VII

    纯数据结构题,没有思维难度.直接用线段树求最大子段和的方法完成树上路径的合并.注意链上合并顺序要符合序列的前后顺序. #include <cstdio> #include <cstr ...

  2. 题解 SP6779 【GSS7 - Can you answer these queries VII】

    题目传送门 题目大意 给出一个\(n\)个点的树,每个点有权值.有\(m\)次操作,每次要么查询一条链上的最大子段和,要么把一条链的权值都修改为一个常数. \(n,m\le 10^5\) 思路 如果是 ...

  3. SPOJ GSS7 - Can you answer these queries VII

    板的不能再板,链剖+线段树或者是LCT随便维护. 感觉唯一要注意的是跳链的时候要对$x$向上跳和$y$向上跳的情况分开讨论,而不能直接$swap$,因为只有两段接触的端点才能相互合并,而且每一次向上跳 ...

  4. SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树

    [题目分析] 问题放到了树上,直接链剖+线段树搞一搞. 调了300行+. (还是码力不够) [代码] #include <cstdio> #include <cstring> ...

  5. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  6. GSS4 2713. Can you answer these queries IV 线段树

    GSS7 Can you answer these queries IV 题目:给出一个数列,原数列和值不超过1e18,有两种操作: 0 x y:修改区间[x,y]所有数开方后向下调整至最近的整数 1 ...

  7. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  8. 6779. Can you answer these queries VII - SPOJ

    Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ). ...

  9. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

随机推荐

  1. Fail2ban 运维管理 服务控制

    启动监禁 启动所有或者单个监禁项目. # 语法:fail2ban-client start [监禁名称] root@ubuntu:~# fail2ban-client start sshd 停止监禁 ...

  2. drools中的条件 when

    目录 1.介绍 2.语法结构 3.模式例子 3.1 单个对象匹配 3.2 匹配任何对象 3.3 带条件匹配 3.3.1 注意事项 3.4 嵌套属性的匹配 3.4.1 访问单个嵌套属性 3.4.2 访问 ...

  3. axios的请求参数格式(get、post、put、delete)

    1.get请求方式: axios.get(url[, config]) // [字符拼接型]axios.get(url?id=123&status=0') // 等同于 axios.get(u ...

  4. Codeforces Round #746

    挺喜欢这场题目的 A: 水,不写了 B: Hemose Shopping 嘲讽自己一下啦~真的是caii 题意:一个数列,我们通过交换两个点(两点满足距离大于等于\(x\)),问能否排序成功. 思路: ...

  5. Bean Validator

    Bean Validator 关于Jakarta EE 2018年03月, Oracle 决定把 JavaEE 移交给开源组织 Eclipse 基金会,并且不再使用Java EE这个名称. 因此jav ...

  6. PyTorch DataSet Normalization torchvision.transforms.Normalize()

         特征缩放, 在这种情况下,我们不仅仅考虑是一个值的数据集,我们考虑的是具有多个特征和相关的值的样本或元素的数据集. 假如正在处理一个人的数据集,           归一化数据集有许多不同的 ...

  7. C#/VB.NET 在Word转PDF时生成目录书签

    当我们在转换Word文档到PDF格式时,想保留Word文档的标题作为PDF书签,那么应该如何操作呢?那么本文将以C#及VB.NET代码为例,介绍如何在Word转PDF时生成目录书签.下面是具体方法和步 ...

  8. iPhone x 的区别

    最近入手两台iPhone x, 均从官网购买,两台分别是2017年和2018年生产,对比了一下,两台还有是一些差别: 首先苹果X使用起来还是非常爽的,没有HOME键,明显比按HOME键方便,因为按HO ...

  9. 七、服务器硬件及RAID配置实战

    一.RAID磁盘阵列介绍 磁盘阵列的全名(Redundant Arrays of Inexpensive Disk,RAID),中文简称是独立冗余磁盘阵列.冗余(如果磁盘出现故障,可以保证数据不丢) ...

  10. 接口偶尔超时,竟又是JVM停顿的锅!

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介 继上次我们JVM停顿十几秒的问题解决后,我们系统终于稳定了,再也不会无故重启了! 这是之前的文章:耗时几个月,终于 ...