codeforces 52C Circular RMQ

C. Circular RMQ
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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).

Examples
input
4
1 2 3 4
4
3 0
3 0 -1
0 1
2 1
output
1
0
0

solution:这就是一个裸的线段树,但是输入却刻意地为难了大家,我的方法是先输入两个整数,再输入一个字符,判断是\0还是空格,进行讨论。然后本题还有一个循环区间的问题,考试的时候想了一会儿,往扩展一倍的方向想了一下,发觉要是这样操作会很麻烦,然后转念一想,其实可以把循环区间切成两个区间去看待([x,n]and[1,y])就可以了。

#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
#define p1 id<<1
#define p2 (id<<1)^1
using namespace std;
int n,m;
ll a[200005];
ll tree[850000],add[850000];
char s[25];
void update(int id,int l,int r,int x,int y,int z)
{
    if(x<=l&&r<=y)
    {
        add[id]=add[id]+(ll)(z);
        return;
    }
    add[p1]+=add[id];
    add[p2]+=add[id];
    add[id]=0;
    int mid=(l+r)/2;
    if(y<=mid) update(p1,l,mid,x,y,z);
    else
    if(x>mid) update(p2,mid+1,r,x,y,z);
    else
    {
        update(p1,l,mid,x,mid,z);
        update(p2,mid+1,r,mid+1,y,z);
    }
    tree[id]=min(tree[p1]+add[p1],tree[p2]+add[p2]);
}
ll lookup(int id,int l,int r,int x,int y)
{
    if(x<=l&&r<=y) return tree[id]+add[id];
    add[p1]+=add[id];
    add[p2]+=add[id];
    add[id]=0;
    int mid=(l+r)/2;
    ll res=0;
    if(y<=mid) res=lookup(p1,l,mid,x,y);
    else
    if(x>mid) res=lookup(p2,mid+1,r,x,y);
    else res=min(lookup(p1,l,mid,x,mid),lookup(p2,mid+1,r,mid+1,y));
    tree[id]=min(tree[p1]+add[p1],tree[p2]+add[p2]);
    return res;
}
void build(int id,int l,int r)
{
    if(l==r)
    {
        tree[id]=a[l];
        add[id]=0;
        return;
    }
    int mid=(l+r)/2;
    build(p1,l,mid);
    build(p2,mid+1,r);
    tree[id]=min(tree[p1],tree[p2]);
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
    build(1,1,n);
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y,z,mark;
        char c;
        x=y=z=mark=0;
        z=0;
        scanf("%d%d",&x,&y);
        x++;y++;
        scanf("%c",&c);
        if(c==' ')
        {
            mark=1;
            scanf("%d",&z);
        }
        if(x<=y)
        {
            if(mark==0) printf("%I64d\n",lookup(1,1,n,x,y)); else update(1,1,n,x,y,z);
        }
        else
        {
            if(mark==0)
            {
                ll s1=lookup(1,1,n,x,n);
                ll s2=lookup(1,1,n,1,y);
                printf("%I64d\n",min(s1,s2));
            }
            else
            {
                update(1,1,n,x,n,z);
                update(1,1,n,1,y,z);
            }
        }
    }
    return 0;
}













你可能感兴趣的:(codeforces 52C Circular RMQ)