農夫約翰打算重修他的農場。他有 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 }