CF52C
题解:很简单的一道题目,注意区间[x,y]x大于y,要分两段。
代码:
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
ll const inf = 1e15;
int const N = 200000 + 10;
ll n,q;
struct Node
{
ll l,r;
ll lazy,mind;
void updata(ll val){
lazy += val;
mind += val;
}
}node[N<<2];
void push_up(ll id){
node[id].mind = min(node[id<<1].mind,node[id<<1|1].mind);
}
void push_down(ll id){
ll lazy =node[id].lazy;
if(lazy){
node[id<<1].updata(lazy);
node[id<<1|1].updata(lazy);
node[id].lazy = 0;
}
}
void build(ll id,ll l,ll r){
node[id].l = l,node[id].r = r;
node[id].lazy = 0;
if(l == r){
scanf("%I64d",&node[id].mind);
}
else{
ll mid = (l + r) >> 1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
push_up(id);
}
}
ll query(ll id,ll L,ll R){
ll l = node[id].l,r = node[id].r;
if(L <= l && r <= R)
return node[id].mind;
else{
push_down(id);
ll mid = (l + r) >> 1;
ll res = inf;
if(L <= mid) res = min(res,query(id<<1,L,R));
if(mid < R) res = min(res,query(id<<1|1,L,R));
return res;
}
}
void updata(ll id,ll L,ll R,ll k){ //将[l,r]区间的每个数加上k
ll l = node[id].l, r = node[id].r;
if(L <= l && r <= R){
node[id].updata(k);
}else{
ll mid = (l + r) >> 1;
push_down(id);
if(L <= mid) updata(id<<1,L,R,k);
if(mid < R) updata(id<<1|1,L,R,k);
push_up(id);
}
}
int main(){
scanf("%I64d",&n);
build(1,1,n);
ll x,y,z;
char t;
scanf("%d",&q);
for(ll i=1;i<=q;i++){
scanf("%I64d%I64d",&x,&y);
x++,y++;
t = getchar();
if(t == ' '){
scanf("%I64d",&z);
if(x > y){
updata(1,x,n,z);
updata(1,1,y,z);
}else updata(1,x,y,z);
}else{
ll mind;
if(x <= y) mind = query(1,x,y);
else mind = min(query(1,x,n),query(1,1,y));
printf("%I64d\n",mind);
}
}
return 0;
}