問題 G:
Find the minimum
時間限制: 2 Sec 內存限制: 128 MB
提交: 83 解決: 20
[提交][狀態][討論版]
題目描述
Given an integer array of size N, we define two kind of operators:
1. Add(L,R,W) : adding an integer W to every element in subarray[L,R];
2. Min(L,R) : returning the minimum number in subarray[L,R].
Note. L and R are the index of array starting from 0. L > R is possible. If L > R, the subarray is composed of array[L], array[L+1].....array[N-1], array[0], array[1],.....array[R].
輸入
There are several test cases, processed to the end of file.
For each test, the first line contains two positive integers N and M. N is the size of array, and M is the number of the operation.
The second line contains N array elements, a1, a2, a3, ...., and an.
Then in the following M lines, each line contains an operation. If the line contains three integers L,R and W, it means the add(L,R,W) operator should be involved. If the line contains two integers L,R , it means the Min(L,R) operator should be involved.
(0<N, M<100,000; 0<= ai <= 10^6; 0 <= L, R <= N – 1, -10^6 <= W <= 10^6。)
輸出
For each Min(L,R) operator in test case, output the return value.
樣例輸入
3 31 2 40 20 0 10 2
樣例輸出
12
提示
the output value may be very large ,long long type is recommended!
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 111111; long long mins[maxn<<4]; long long col[maxn<<4]; void PushUP(int rt) { mins[rt] = min(mins[rt<<1] , mins[rt<<1|1]); } void PushDown(int rt,int l,int r) { if (col[rt]) { col[rt<<1]+=col[rt]; col[rt<<1|1]+=col[rt]; mins[rt<<1]+=col[rt]; mins[rt<<1|1]+=col[rt]; col[rt] = 0; } } void build(int l,int r,int rt) { col[rt]=0; if (l == r) { scanf("%lld",&mins[rt]);; return; } int m = (l + r) >> 1; build(l , m , rt << 1); build(m + 1 , r , rt << 1 | 1); PushUP(rt); } void update(int L,int R,long long add,int l,int r,int rt) { if (L<=l && r<=R) { mins[rt]+=add; col[rt]+=add; return ; } PushDown(rt,l,r); int m = (l + r) >> 1; if(L<=m) update(L,R,add,l , m , rt << 1); if(R>m) update(L,R,add,m + 1 , r , rt << 1 | 1); PushUP(rt); } long long ret; void query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { ret=min(ret,mins[rt]); return; } int m = (l + r) >> 1; PushDown(rt,l,r); if (L <= m) query(L , R , l , m , rt << 1); if (R > m) query(L , R , m + 1 , r , rt << 1 | 1); } int main() { int n,t; long long v; int l,r; while(scanf("%d%d",&n,&t)!=EOF) { build(1,n,1); while(t--) { int flag=1; scanf("%d%d",&l,&r); if(getchar()==' ') {scanf("%lld",&v);flag=0;} l++;r++; if(flag) { ret=0x7fffffffffffffffLL; if(l>r) { query(l,n,1,n,1); query(1,r,1,n,1); printf("%lld\n",ret); } else { query(l,r,1,n,1); printf("%lld\n",ret); } } else { if(l>r){ update(l,n,v,1,n,1); update(1,r,v,1,n,1); } else update(l,r,v,1,n,1); } } } return 0; }