Circular RMQ

来源:互联网 发布:shell编程入门书籍推荐 编辑:程序博客网 时间:2024/05/20 09:27

Description

You are given circular array a0, a1, ..., an - 1. There are two types of operations with it:

  • inc(lf, rg, v) — this operation increases each element on the segment [lf, rg] (inclusively) by v;
  • rmq(lf, rg) — this operation returns minimal value on the segment [lf, rg] (inclusively).

Assume segments to be circular, so if n = 5 and lf = 3, rg = 1, it means the index sequence: 3, 4, 0, 1.

Write program to process given sequence of operations.

Input

The first line contains integer n (1 ≤ n ≤ 200000). The next line contains initial state of the array: a0, a1, ..., an - 1 ( - 106 ≤ ai ≤ 106), ai are integer. The third line contains integer m (0 ≤ m ≤ 200000), m — the number of operartons. Next m lines contain one operation each. If line contains two integer lf, rg (0 ≤ lf, rg ≤ n - 1) it means rmq operation, it contains three integers lf, rg, v (0 ≤ lf, rg ≤ n - 1; - 106 ≤ v ≤ 106) — inc operation.

Output

For each rmq operation write result for it. Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to usecout (also you may use %I64d).

Sample Input

Input
41 2 3 443 03 0 -10 12 1
Output
10

0

线段树成段更新,注意输入判断和a<b的变化

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;typedef long long ll;#define maxn 800080#define MAX 0x3f3f3f3fll sum[maxn];ll col[maxn];void Pushup(int rt){    sum[rt]=min(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){    col[rt]=0;    if(l==r)    {        scanf("%I64d",&sum[rt]);        return ;    }    int mid=(l+r)/2;    build(l,mid,rt<<1);    build(mid+1,r,rt<<1|1);    Pushup(rt);}void Pushdown(int rt){    if(col[rt])    {        col[rt<<1]+=col[rt];        col[rt<<1|1]+=col[rt];        sum[rt<<1]+=col[rt];        sum[rt<<1|1]+=col[rt];        col[rt]=0;    }}void Update(int L,int R,ll c,int l,int r,int rt){    if(L<=l&&r<=R)    {        col[rt]+=c;        sum[rt]+=c;        return ;    }    Pushdown(rt);    int mid=(l+r)/2;    if(L<=mid) Update(L,R,c,l,mid,rt<<1);    if(R>mid) Update(L,R,c,mid+1,r,rt<<1|1);    Pushup(rt);}ll Query(int L,int R,int l,int r,int rt){    ll  ret=MAX;    if(L<=l&&r<=R)       return sum[rt];    Pushdown(rt);    int mid=(l+r)>>1;    if(L<=mid) ret=min(ret,Query(L,R,l,mid,rt<<1));    if(R>mid) ret=min(ret,Query(L,R,mid+1,r,rt<<1|1));    return ret;}int main(){    int n,m;    int a,b;    ll c;    char ch;    scanf("%d",&n);    build(1,n,1);    scanf("%d",&m);    while(m--)    {        scanf("%d%d%c",&a,&b,&ch);       if(ch==' ')       {           scanf("%I64d",&c);           if(a>b)           {              Update(1,b+1,c,1,n,1);              Update(a+1,n,c,1,n,1);           }           else              Update(a+1,b+1,c,1,n,1);       }       else       {           if(a>b)               printf("%I64d\n",min(Query(1,b+1,1,n,1),Query(a+1,n,1,n,1)));            else               printf("%I64d\n",Query(a+1,b+1,1,n,1));       }    }    return 0;}


0 0
原创粉丝点击