题目大意:给定一棵树,每个点有一个整数权值(可以是负数),要求支持两种操作:
1.链上加
2.链上绝对值之和
由于加的数保证非负,因此一个负数变成一个正数最多有 n <script type="math/tex" id="MathJax-Element-23">n</script>次
树链剖分,在线段树中维护一下区间最大负数即可
不知道为何 写了两个线段树就TLE 把两个线段树合并成一个就7s过了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct Segtree{
Segtree *ls,*rs;
long long sum,mark;
int cnt;//区间中负数的个数
pair<int,int> max_pos;
void* operator new (size_t)
{
static Segtree mempool[M<<1],*C=mempool;
return C++;
}
void Add(int x,int y,long long val)
{
sum+=(y-x+1-2*cnt)*val;
mark+=val;
if(max_pos.first!=(signed)0xefefefef)
max_pos.first+=val;
}
void Push_Up(int x,int y)
{
sum=ls->sum+rs->sum;
cnt=ls->cnt+rs->cnt;
max_pos=max(l