农夫约翰打算重修他的农场。他有 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 ",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 ",quary(1,1,n,l,r)); 100 } 101 } 102 return 0; 103 }