【UOJ 169】【UR #11】元旦老人与数列
此题与洛谷P6242 【模板】线段树 3为孪生题
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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 1e18
#define mod 998244353
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
LL n,m,k;
LL minf[MS<<2];
LL minse[MS<<2];
LL laminf[MS<<2];
LL laoth[MS<<2];
LL hisminf[MS<<2];
LL lahisminf[MS<<2];
LL lahisoth[MS<<2];
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){
minf[rt] = min(minf[ls],minf[rs]);
hisminf[rt] = min(hisminf[ls],hisminf[rs]);
if(minf[ls] == minf[rs])
minse[rt] = min(minse[ls],minse[rs]);
else if(minf[ls] < minf[rs])
minse[rt] = min(minse[ls],minf[rs]);
else
minse[rt] = min(minf[ls],minse[rs]);
}
void update(int rt,LL k1,LL k2,LL k3,LL k4){
hisminf[rt] = min(hisminf[rt],minf[rt]+k3);
lahisminf[rt] = min(lahisminf[rt],laminf[rt]+k3);
lahisoth[rt] = min(lahisoth[rt],laoth[rt]+k4);
minf[rt] += k1;
if(minse[rt] != INF) minse[rt] += k2;
laminf[rt] += k1;
laoth[rt] += k2;
}
void push_down(int rt){
LL minn = min(minf[ls],minf[rs]);
if(minf[ls] == minn) update(ls,laminf[rt],laoth[rt],lahisminf[rt],lahisoth[rt]);
else update(ls,laoth[rt],laoth[rt],lahisoth[rt],lahisoth[rt]);
if(minf[rs] == minn) update(rs,laminf[rt],laoth[rt],lahisminf[rt],lahisoth[rt]);
else update(rs,laoth[rt],laoth[rt],lahisoth[rt],lahisoth[rt]);
laminf[rt] = laoth[rt] = 0;
lahisminf[rt] = lahisoth[rt] = 0;
}
void build(int l,int r,int rt){
laminf[rt] = 0;
laoth[rt] = 0;
lahisminf[rt] = 0;
lahisoth[rt] = 0;
if(l == r){
LL x;
x = read();
minf[rt] = x;
minse[rt] = INF;
hisminf[rt] = x;
return;
}
int m = l+r>>1;
build(l,m,ls);
build(m+1,r,rs);
push_up(rt);
}
void update_add(int L,int R,int l,int r,int rt,LL val){
if(L <= l && r <= R){
update(rt,val,val,val,val);
return;
}
push_down(rt);
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_max(int L,int R,int l,int r,int rt,LL val){
if(minf[rt] >= val) return;
if(L <= l && r <= R && minse[rt] > val){
update(rt,val-minf[rt],0,val-minf[rt],0);
return;
}
push_down(rt);
int m = l+r>>1;
if(m >= L) update_max(L,R,l,m,ls,val);
if(m < R) update_max(L,R,m+1,r,rs,val);
push_up(rt);
}
LL get_min(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) return minf[rt];
push_down(rt);
LL ans = INF;
int m = l+r>>1;
if(m >= L) ans = min(ans,get_min(L,R,l,m,ls));
if(m < R) ans = min(ans,get_min(L,R,m+1,r,rs));
return ans;
}
LL get_hismin(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) return hisminf[rt];
push_down(rt);
LL ans = INF;
int m = l+r>>1;
if(m >= L) ans = min(ans,get_hismin(L,R,l,m,ls));
if(m < R) ans = min(ans,get_hismin(L,R,m+1,r,rs));
return ans;
}
int main() {
//ios::sync_with_stdio(false);
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_add(l,r,1,n,1,val);
}
else if(op == 2){
val = read();
update_max(l,r,1,n,1,val);
}
else if(op == 3){
printf("%lld\n",get_min(l,r,1,n,1));
}
else{
printf("%lld\n",get_hismin(l,r,1,n,1));
}
}
return 0;
}