Find the minimum
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 90 Solved: 22
[Submit][Status][Web Board]
Description
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].
Input
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。)
Output
For each Min(L,R) operator in test case, output the return value.
Sample Input
Sample Output
題意:
感悟:
代碼:
#include<iostream>
#include<cstdio>
//#define MIN(a,b) (a>b?b:a) 用這個會出現*Accepted-24924,( 百度了一下,沒度出來,不知道是什麼玩意兒)
using namespace std;
struct node{
int left,right,mid,x,add;
}tree[400010];
int n,m,L,R,w,a[1000010];
long long MIN(long long a,long long b)//這個就可以直接過了
{
return a > b?b:a;
}
void build(int le,int ri,int num)//構建一個線段樹
{
tree[num].left= le;
tree[num].right = ri;
tree[num].add = 0;
tree[num].mid = (le + ri) /2;
if(le!=ri)
{
build(le,tree[num].mid,num*2);
build(tree[num].mid+1,ri,num*2+1);
tree[num].x=MIN(tree[num*2].x,tree[num*2+1].x);
}
else
{
tree[num].x=a[le];
return ;
}
}
void change(int le,int ri,int num,int cha)
{
if(tree[num].left==le&&tree[num].right==ri)
{
tree[num].add += cha;
return ;
}
if(tree[num].add)
{
tree[num*2].add+=tree[num].add;//將加的數傳下去
tree[num*2+1].add += tree[num].add;
tree[num].add=0;
}
if(ri<=tree[num].mid)//這裏被坑過,必須是<=,避免出現tree[num].mid+1比ri大的情況,不然會出現Runtime Error
change(le,ri,num*2,cha);
else if(le>tree[num].mid)
change(le,ri,num*2+1,cha);
else
{
change(le,tree[num].mid,num*2,cha);
change(tree[num].mid+1,ri,num*2+1,cha);
}
tree[num].x=MIN(tree[num*2].x+tree[num*2].add,tree[num*2+1].x+tree[num*2+1].add);
// printf("%d %d\n",num,tree[num].x);
}
int findMIN(int le,int ri,int num)
{
int ls,rs;
if(tree[num].left==le&&tree[num].right==ri)
return tree[num].x+tree[num].add;
ls=num*2;rs=num*2+1;
if(tree[num].add)
{
tree[num].x += tree[num].add;
tree[ls].add += tree[num].add;
tree[rs].add += tree[num].add;
tree[num].add = 0;
}
// printf("%d %d\n",num,tree[num].x);
if(le>tree[num].mid)
return findMIN(le,ri,rs);
else if(ri<=tree[num].mid)
return findMIN(le,ri,ls);
else
{
return MIN(findMIN(le,tree[num].mid,ls),findMIN(tree[num].mid+1,ri,rs));
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
int i;char z;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
for(i=0;i<m;i++)
{
scanf("%d %d%c",&L,&R,&z);
L++;R++;
if(z=='\n')
{
if(L<=R)
printf("%d\n",findMIN(L,R,1));
else
printf("%d\n",MIN(findMIN(L,n,1),findMIN(1,R,1)));
}
else
{
scanf("%d",&w);
if(L<=R)
change(L,R,1,w);
else
{
change(L,n,1,w);
change(1,R,1,w);
}
}
}
}
return 0;
}