CodeForces 52C Circular RMQ (区间更新线段树)

来源:互联网 发布:军华软件下载 编辑:程序博客网 时间:2024/06/01 09:53
C - Circular RMQ
Time Limit:3000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Submit Status

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 use cout (also you may use %I64d).

Sample Input

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

#include<iostream>#include<cstdio>#define MAX 200005#define INF 0x3ffffffflong long c,tree[4*MAX],add[4*MAX];long long _min(long long a,long long b){    return a<b?a:b;}void pushdown(int n){    if(add[n]!=0)    {        add[2*n]+=add[n];        add[2*n+1]+=add[n];        tree[2*n]+=add[n];        tree[2*n+1]+=add[n];        add[n]=0;    }}void pushup(int n){    tree[n]=_min(tree[2*n],tree[2*n+1]);}void build(int s,int e,int n){    add[n]=0;    if(s==e)    {        scanf("%I64d",&tree[n]);        return ;    }    int mid=(s+e)/2;    build(s,mid,2*n);    build(mid+1,e,2*n+1);    pushup(n);}void modify(int a,int b,long long c,int s,int e,int n){    if(a<=s&&e<=b)    {        add[n]+=c;        tree[n]+=c;        return ;    }    pushdown(n);    int mid=(s+e)/2;    if(a<=mid) modify(a,b,c,s,mid,2*n);    if(mid<b) modify(a,b,c,mid+1,e,2*n+1);    pushup(n);}long long query(int a,int b,int s,int e,int n){    if(a<=s&&e<=b)    {        return tree[n];    }    pushdown(n);    int mid=(e+s)/2;    long long s2,s1;s1=s2=INF;    if(a<=mid) s1=_min(s1,query(a,b,s,mid,2*n));    if(mid<b) s2=_min(s2,query(a,b,mid+1,e,2*n+1));    return _min(s1,s2);}int main(){    int n,m,i,a,b;    char q;    scanf("%d",&n);    build(1,n,1);    scanf("%d",&m);    while(m--)    {        scanf("%d%d",&a,&b);        q=getchar();        if(q==' ')        {            scanf("%I64d",&c);            if(a<=b)            {                modify(a+1,b+1,c,1,n,1);            }            else            {                  modify(a+1,n,c,1,n,1);                  modify(1,b+1,c,1,n,1);            }        }        else       {           if(a<=b) printf("%I64d\n",query(a+1,b+1,1,n,1) );           else           {               long long s1=query(a+1,n,1,n,1);               long long s2=query(1,b+1,1,n,1);               printf("%I64d\n",_min(s1,s2) );           }       }    }    return 0;}

0 0