You are given circular array a0, a1, ..., an - 1. There are two types of operations with it:
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
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; }