codeforces 52 C. Circular RMQ (线段树区间更新,区间询问)

题目链接

题意:一个循环数列,两种操作,一种是把某段区间中加上v,另一种是询问某区间的最小值。对于每个询问,输出答案。

思路:区间更新+区间询问的模板题....

注意体会pushdown以及update的时候。。。

要同时更新tree数组和lazy数组。。。

读入的时候可以用sscanf判断操作类型。。。

  1/* ***********************************************
  2Author :111qqz
  3Created Time :Mon 26 Sep 2016 05:30:21 AM CST
  4File Name :code/cf/problem/52C.cpp
  5************************************************ */
  6#include <cstdio>
  7#include <cstring>
  8#include <iostream>
  9#include <algorithm>
 10#include <vector>
 11#include <queue>
 12#include <set>
 13#include <map>
 14#include <string>
 15#include <cmath>
 16#include <cstdlib>
 17#include <ctime>
 18#define fst first
 19#define sec second
 20#define lson l,m,rt<<1
 21#define rson m+1,r,rt<<1|1
 22#define ms(a,x) memset(a,x,sizeof(a))
 23typedef long long LL;
 24#define pi pair < int ,int >
 25#define MP make_pair
 26using namespace std;
 27const double eps = 1E-8;
 28const int dx4[4]={1,0,0,-1};
 29const int dy4[4]={0,-1,1,0};
 30const int inf = 0x3f3f3f3f;
 31const int N=2E5+7;
 32int n,m;
 33LL a[N];
 34LL tree[N<<2];
 35LL lazy[N<<2];
 36void PushUp( int rt)
 37{
 38    tree[rt] = min(tree[rt<<1],tree[rt<<1|1]);
 39}
 40void PushDown( int rt)
 41{
 42    if (lazy[rt])
 43    {
 44	lazy[rt<<1] += lazy[rt];
 45	lazy[rt<<1|1] +=lazy[rt];
 46	tree[rt<<1] +=lazy[rt];
 47	tree[rt<<1|1] +=lazy[rt];
 48	lazy[rt] =  0;
 49    }
 50}
 51void build(  int l,int r,int rt)
 52{
 53    if (rt)
 54    if (l==r)
 55    {
 56	tree[rt] = a[l] ;
 57	return;
 58    }
 59    int m = (l+r)>>1;
 60    build(lson);
 61    build(rson);
 62    PushUp(rt);
 63}
 64void update(int L,int R,LL sc,int l,int r,int rt)
 65{
 66    if (L<=l&&r<=R)
 67    {
 68	lazy[rt] +=sc;
 69	tree[rt] +=sc;
 70	return;
 71    }
 72    PushDown(rt);
 73    int m = (l+r)>>1;
 74    if (L<=m) update(L,R,sc,lson);
 75    if (R>=m+1) update(L,R,sc,rson);
 76    PushUp(rt);
 77}
 78LL query( int L,int R,int l,int r,int rt)
 79{
 80    if (L<=l&&r<=R) return tree[rt];
 81    PushDown(rt);
 82    int m = (l+r)>>1;
 83    LL ret = 1LL<<60;
 84    if (L<=m) ret = min(ret,query(L,R,lson));
 85    if (R>=m+1) ret = min(ret,query(L,R,rson));
 86    return ret;
 87}
 88int main()
 89{
 90	#ifndef  ONLINE_JUDGE 
 91	freopen("code/in.txt","r",stdin);
 92  #endif
 93	scanf("%d",&n);
 94	for ( int i = 1 ; i <= n ; i++) scanf("%lld",&a[i]);
 95	scanf("%d",&m);
 96	getchar(); //记得回车符。。。
 97	build(1,n,1);
 98	while (m--)
 99	{
100	    char str[50];
101	    gets(str);
102	    int l,r;
103	    LL v;
104	    if (sscanf(str,"%d%d%lld",&l,&r,&v)==3)
105	    {
106		l++;
107		r++;
108		if (l<=r)
109		update(l,r,v,1,n,1);
110		else update(l,n,v,1,n,1),update(1,r,v,1,n,1);
111	    }else
112	    {
113		l++;
114		r++;
115		LL ans;
116		if (l<=r)
117		 ans = query(l,r,1,n,1);
118		else ans = min(query(1,r,1,n,1),query(l,n,1,n,1));
119		printf("%lld\n",ans);
120	    }
121	}
122  #ifndef ONLINE_JUDGE  
123  fclose(stdin);
124  #endif
125    return 0;
126}