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.
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.
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).
4 1 2 3 4 4 3 0 3 0 -1 0 1 2 1
1 0 0
题意:给出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; }