标签:targe namespace efi min 最大 uil unsigned -- code
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma GCC optimize(2)
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define MS 500009
#define INF 20000009
#define mod 1000000007
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define M 11431471
#define B 231
#define MM 37101101
#define BB 312
LL n,m,k;
LL sum[MS<<2]; // 区间和
LL maxf[MS<<2]; // 区间最大值
LL cntf[MS<<2]; // 区间最大值个数
LL maxse[MS<<2]; // 区间第二大值
LL lamaxf[MS<<2]; // la_区间最大值需加的数
LL laoth[MS<<2]; // la_区间非最大值需加的数
ll read(){
char c=getchar();ll s=0,f=1;
for(;!isdigit(c);c=getchar())if(c==‘-‘)f=-1;
for(;isdigit(c);c=getchar())s=s*10+c-48;
return s*f;
}
void push_up(int rt){
sum[rt] = sum[ls] + sum[rs];
maxf[rt] = max(maxf[ls],maxf[rs]);
if(maxf[ls] == maxf[rs]){
cntf[rt] = cntf[ls] + cntf[rs];
maxse[rt] = max(maxse[ls],maxse[rs]);
}
else if(maxf[ls] > maxf[rs]){
cntf[rt] = cntf[ls];
maxse[rt] = max(maxse[ls],maxf[rs]);
}
else{
cntf[rt] = cntf[rs];
maxse[rt] = max(maxf[ls],maxse[rs]);
}
}
void build(int l,int r,int rt){
lamaxf[rt] = 0;
laoth[rt] = 0;
if(l == r){
LL x;
x = read();
sum[rt] = x;
maxf[rt] = x;
cntf[rt] = 1;
maxse[rt] = -1e18;
return;
}
int m = l+r>>1;
build(l,m,ls);
build(m+1,r,rs);
push_up(rt);
}
void update(int rt,int l,int r,LL k1,LL k2){
sum[rt] += cntf[rt]*k1+(r-l+1-cntf[rt])*k2;
maxf[rt] += k1;
if(maxse[rt] != -1e18) maxse[rt] += k2;
lamaxf[rt] += k1;
laoth[rt] += k2;
}
void push_down(int rt,int l,int r){
LL m = l+r>>1;
LL maxn = max(maxf[ls],maxf[rs]);
if(maxf[ls] == maxn) update(ls,l,m,lamaxf[rt],laoth[rt]);
else update(ls,l,m,laoth[rt],laoth[rt]);
if(maxf[rs] == maxn) update(rs,m+1,r,lamaxf[rt],laoth[rt]);
else update(rs,m+1,r,laoth[rt],laoth[rt]);
lamaxf[rt] = laoth[rt] = 0;
}
void update_add(int L,int R,int l,int r,int rt,LL val){
if(L <= l && r <= R){
update(rt,l,r,val,val);
return;
}
push_down(rt,l,r);
int m = l+r>>1;
if(m >= L) update_add(L,R,l,m,ls,val);
if(m < R) update_add(L,R,m+1,r,rs,val);
push_up(rt);
}
void update_min(int L,int R,int l,int r,int rt,LL val){
if(maxf[rt] <= val) return;
if(L <= l && r <= R && val > maxse[rt]){
update(rt,l,r,val-maxf[rt],0);
return;
}
push_down(rt,l,r);
int m = l+r>>1;
if(m >= L) update_min(L,R,l,m,ls,val);
if(m < R) update_min(L,R,m+1,r,rs,val);
push_up(rt);
}
LL get_sum(int L,int R,int l,int r,int rt){
if(L <= l && r <= R){
return sum[rt];
}
push_down(rt,l,r);
LL ans = 0;
int m = l+r>>1;
if(m >= L) ans += get_sum(L,R,l,m,ls);
if(m < R) ans += get_sum(L,R,m+1,r,rs);
return ans;
}
void solve(){
n = read() ,m = read();
build(1,n,1);
while(m--){
LL op,l,r,val;
op = read();
l = read() ,r = read();
if(op == 1){
val = read();
update_min(l,r,1,n,1,val);
}
else if(op == 2){
val = read();
update_add(l,r,1,n,1,val);
}
else printf("%lld\n",get_sum(l,r,1,n,1));
}
}
int main() {
//ios::sync_with_stdio(false);
LL te;
te = 1;
while(te--){
solve();
}
return 0;
}
【WZOI 21/239】 Picks loves segment tree
标签:targe namespace efi min 最大 uil unsigned -- code
原文地址:https://www.cnblogs.com/Tecode/p/14425782.html