题目地址:http://codeforces.com/problemset/problem/52/C
线段树区间更新水题。
代码如下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
int min1[1000000], lazy[1000000];
void PushUp(int rt)
{
min1[rt]=min(min1[rt<<1],min1[rt<<1|1]);
}
void PushDown(int rt)
{
if(lazy[rt])
{
min1[rt<<1|1]+=lazy[rt];
min1[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
lazy[rt<<1]+=lazy[rt];
lazy[rt]=0;
}
}
void build(int l, int r, int rt)
{
if(l==r)
{
scanf("%d",&min1[rt]);
return ;
}
int mid=l+r>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int ll, int rr, int x, int l, int r, int rt)
{
if(ll<=l&&rr>=r)
{
lazy[rt]+=x;
min1[rt]+=x;
return ;
}
PushDown(rt);
int mid=l+r>>1;
if(ll<=mid) update(ll,rr,x,lson);
if(rr>mid) update(ll,rr,x,rson);
PushUp(rt);
}
int query(int ll, int rr, int l, int r, int rt)
{
if(ll<=l&&rr>=r)
{
return min1[rt];
}
PushDown(rt);
int ans=INF, mid=l+r>>1;
if(ll<=mid) ans=min(ans,query(ll,rr,lson));
if(rr>mid) ans=min(ans,query(ll,rr,rson));
return ans;
}
int main()
{
int n, l, r, x, q, i;
scanf("%d",&n);
build(0,n-1,1);
scanf("%d",&q);
memset(lazy,0,sizeof(lazy));
while(q--)
{
scanf("%d%d",&l,&r);
if(getchar()==' ')
{
scanf("%d",&x);
if(l>r)
{
update(l,n-1,x,0,n-1,1);
update(0,r,x,0,n-1,1);
/*for(i=1;i<=7;i++)
printf("%d ",min1[i]);
printf("\n");*/
}
else
{
update(l,r,x,0,n-1,1);
/*for(i=1;i<=7;i++)
printf("%d ",min1[i]);
printf("\n");*/
}
}
else
{
if(l>r)
{
int ans=min(query(l,n-1,0,n-1,1),query(0,r,0,n-1,1));
printf("%d\n",ans);
}
else
{
int ans=query(l,r,0,n-1,1);
printf("%d\n",ans);
}
}
}
return 0;
}