USACO 2015 December Contest Counting Haybales (bzoj4392)

农夫约翰打算重修他的农场。他有 N 块土地,连续排列成一行,标号为 1…N。在每块土地上有任意数量的草堆。他可以发出三种指令:
1) 对一个连续区间的土地,每块土地增加相同数量的草堆。
2) 对一个连续区间的土地,输出其中最少的草堆数量。
3) 对一个连续区间的土地,输出草堆数量总数。

第一行两个正整数,N (1≤N≤200,000) 和 Q (1≤Q≤100,000)。
下一行是N个非负整数,最大100,000,表示每块土地上有多少个草堆。
以下Q行,每行一单个大写字母开头(M,P或S),空格后跟随两个正整数 A 和 B (1≤A≤B≤N), 或者三个正整数 A, B, 和 C (1≤A≤B≤N; 1≤C≤100,000)。当且仅当第一个字母是 P 时,是三个正整数。
当该字母是M,输出区间A…B的最小草堆数。
当该字母是P,在区间A…B,每块土地增加C堆草。
当该字母是M,输出区间A…B的草堆数之和。

每行一个数字,用于响应'M' 或 'S' 命令。


裸线段树,不过要用long long ,只是add 的 v没加就让我wa了好久。。

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <queue>
  6 #include <vector>
  7 using namespace std;
  8 const int maxn=2e5+10;
  9 const long long inf=1e19;
 10 int n,m;
 11 int a[maxn];
 12 struct hh
 13 {
 14   long long mark,val,sum;
 15 }tree[maxn*4];
 16 template <class T> void read(T&x)
 17 {
 18   x=0;char c=getchar();int f=0;
 19   while(c<'0'||c>'9'){f|=(c=='-');c=getchar();}
 20   while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
 21   x=f?-x:x;
 22 }
 23 void pushdown(int root,int l,int r)
 24 {
 25   if(tree[root].mark)
 26   {
 27       int mid=l+r>>1;
 28       tree[root<<1].mark+=tree[root].mark;
 29       tree[root<<1|1].mark+=tree[root].mark;
 30       tree[root<<1].val+=tree[root].mark;
 31       tree[root<<1|1].val+=tree[root].mark;
 32       tree[root<<1].sum+=(mid-l+1)*tree[root].mark;
 33       tree[root<<1|1].sum+=(r-mid)*tree[root].mark;
 34       tree[root].mark=0;
 35   }
 36   return;
 37   
 38 }
 39 void build(int root,int l,int r)
 40 {
 41   if(l==r){tree[root].sum=tree[root].val=a[l];return;}
 42   int mid=l+r>>1;
 43   build(root<<1,l,mid);
 44   build(root<<1|1,mid+1,r);
 45   tree[root].val=min(tree[root<<1].val,tree[root<<1|1].val);
 46   tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
 47   return;
 48 }
 49 void add(int root,int nl,int nr,int al,int ar,long long  v)
 50 {
 51   if(nl>ar||nr<al)return;
 52   if(nl>=al&&nr<=ar){tree[root].mark+=v;tree[root].val+=v;tree[root].sum+=(nr-nl+1)*v;return;}
 53   pushdown(root,nl,nr);
 54   int mid=nl+nr>>1;
 55   add(root<<1,nl,mid,al,ar,v);
 56   add(root<<1|1,mid+1,nr,al,ar,v);
 57   tree[root].val=min(tree[root<<1].val,tree[root<<1|1].val);
 58   tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
 59   return;
 60 }
 61 long long query(int root,int nl,int nr,int ql,int qr)
 62 {
 63   if(nl>qr||nr<ql)return inf;
 64   if(nl>=ql&&nr<=qr)return tree[root].val;
 65   pushdown(root,nl,nr);
 66   int mid=nl+nr>>1;
 67   return min(query(root<<1,nl,mid,ql,qr),query(root<<1|1,mid+1,nr,ql,qr));
 68 }
 69 long long quary(int root,int nl,int nr,int ql,int qr)
 70 {
 71   if(nl>qr||nr<ql)return 0;
 72   if(nl>=ql&&nr<=qr)return tree[root].sum;
 73   pushdown(root,nl,nr);
 74   int mid=nl+nr>>1;
 75   return quary(root<<1,nl,mid,ql,qr)+quary(root<<1|1,mid+1,nr,ql,qr);
 76 }
 77 int main()
 78 {
 79   read(n);read(m);
 80   for(int i=1;i<=n;i++)read(a[i]);
 81   build(1,1,n);
 82   for(int i=1;i<=m;i++)
 83   {
 84     char s[3];
 85     scanf("%s",s);
 86     if(s[0]=='M')
 87     {
 88       int l,r;read(l);read(r);
 89       printf("%lld\n",query(1,1,n,l,r));
 90     }
 91     else if(s[0]=='P')
 92     {
 93       int l,r,w;read(l);read(r);read(w);
 94       add(1,1,n,l,r,w);
 95     }
 96     else if(s[0]=='S')
 97     {
 98       int l,r;read(l);read(r);
 99       printf("%lld\n",quary(1,1,n,l,r));
100     }
101   }
102   return 0;
103 }

 

posted @ 2018-07-09 18:46  新手-周  阅读(156)  评论(0编辑  收藏  举报