CF 52C Circular RMQ(区间更新,区间询问)

来源:互联网 发布:js怎么判断undefined 编辑:程序博客网 时间:2024/05/16 12:38
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 andlf = 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 integerm (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 meansrmq 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 test(s)
Input
41 2 3 443 03 0 -10 12 1
Output
100
题意:给出n个数,m次操作,操作有[a,b]区间每个数加上c或者求[a,b]区间的最小值。
思路:线段树。
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <vector>#include <cmath>#include <stack>#include <cstdlib>#define L(rt) (rt<<1)#define R(rt) (rt<<1|1)using namespace std;const int maxn=200005;struct node{    int l,r;    long long add,ans;}tree[maxn*4];int num[maxn];int n;void build(int l,int r,int rt){    tree[rt].l=l;    tree[rt].r=r;    tree[rt].add=0;    if(l==r)    {        tree[rt].ans=num[l];        return;    }    int mid=(l+r)>>1;    build(l,mid,L(rt));    build(mid+1,r,R(rt));    tree[rt].ans=min(tree[L(rt)].ans,tree[R(rt)].ans);}void update(int l,int r,int rt,int val){    if(tree[rt].l==l&&tree[rt].r==r)    {        tree[rt].ans+=val;        tree[rt].add+=val;        return;    }    if(tree[rt].add)    {        tree[L(rt)].ans+=tree[rt].add;        tree[L(rt)].add+=tree[rt].add;        tree[R(rt)].ans+=tree[rt].add;        tree[R(rt)].add+=tree[rt].add;        tree[rt].add=0;    }    if(r<=tree[L(rt)].r) update(l,r,L(rt),val);    else if(l>=tree[R(rt)].l) update(l,r,R(rt),val);    else    {        update(l,tree[L(rt)].r,L(rt),val);        update(tree[R(rt)].l,r,R(rt),val);    }    tree[rt].ans=min(tree[L(rt)].ans,tree[R(rt)].ans);}long long query(int l,int r,int rt){    if(tree[rt].l==l&&tree[rt].r==r)    return tree[rt].ans;    if(tree[rt].add)    {        tree[L(rt)].ans+=tree[rt].add;        tree[L(rt)].add+=tree[rt].add;        tree[R(rt)].ans+=tree[rt].add;        tree[R(rt)].add+=tree[rt].add;        tree[rt].add=0;    }    if(r<=tree[L(rt)].r) return query(l,r,L(rt));    else if(l>=tree[R(rt)].l) return query(l,r,R(rt));    else return min(query(l,tree[L(rt)].r,L(rt)),query(tree[R(rt)].l,r,R(rt)));}int main(){    char ch;    int a,b,c,m,ans;    while(cin>>n)    {        for(int i=1;i<=n;i++)        cin>>num[i];        build(1,n,1);        cin>>m;        while(m--)        {            int flag=0;           cin>>a>>b;           if((ch=getchar())==' ')           {               flag=1;               cin>>c;           }           a++;           b++;           if(!flag)           {               if(b>=a) ans=query(a,b,1);               else               ans=min(query(a,n,1),query(1,b,1));               cout<<ans<<endl;           }           else           {               if(b>=a) update(a,b,1,c);               else               {                   update(a,n,1,c);                   update(1,b,1,c);               }           }        }    }    return 0;}


原创粉丝点击