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' 命令。ui


裸線段樹,不過要用long long ,只是add 的 v沒加就讓我wa了很久。。spa

  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 }
相關文章
相關標籤/搜索