如題,已知一個數列,你須要進行下面兩種操做:ios
1.將某區間每個數加上xide
2.求出某區間每個數的和spa
輸入格式:code
第一行包含兩個整數N、M,分別表示該數列數字的個數和操做的總個數。blog
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。get
接下來M行每行包含3或4個整數,表示一個操做,具體以下:io
操做1: 格式:1 x y k 含義:將區間[x,y]內每一個數加上kevent
操做2: 格式:2 x y 含義:輸出區間[x,y]內每一個數的和class
輸出格式:stream
輸出包含若干行整數,即爲全部操做2的結果。
時空限制:1000ms,128M
數據規模:
對於30%的數據:N<=8,M<=10
對於70%的數據:N<=1000,M<=10000
對於100%的數據:N<=100000,M<=100000
(數據已通過增強^_^,保證在int64/long long數據範圍內)
樣例說明:
1 #include<iostream> 2 #include<cstdio> 3 #define ll long long 4 using namespace std; 5 ll read() 6 { 7 ll x=0,f=1; 8 char ch=getchar(); 9 while(ch<'0'||ch>'9') 10 { 11 if(ch=='-') 12 f=-1; 13 ch=getchar(); 14 } 15 while(ch>='0'&&ch<='9') 16 { 17 x=x*10+ch-'0'; 18 ch=getchar(); 19 } 20 return x*f; 21 } 22 ll n,m,a,b,t,x,y,z; 23 ll tree[100005],tree1[100005]; 24 void add(ll*z,ll x,ll num) 25 { 26 while(x<=n) 27 { 28 z[x]+=num; 29 x+=x&(-x); 30 } 31 } 32 ll getsum(ll*z,ll x) 33 { 34 ll sum=0; 35 while(x>0) 36 { 37 sum+=z[x]; 38 x-=x&(-x); 39 } 40 return sum; 41 } 42 int main() 43 { 44 n=read(),m=read(); 45 for(ll i=1; i<=n; i++) 46 { 47 a=read(); 48 b=a-b; 49 add(tree,i,b); 50 add(tree1,i,(i-1)*b); 51 b=a; 52 } 53 for(ll i=1; i<=m; i++) 54 { 55 t=read(); 56 if (t==1) 57 { 58 x=read(),y=read(),z=read(); 59 add(tree,x,z); 60 add(tree,y+1,-z); 61 add(tree1,x,z*(x-1)); 62 add(tree1,y+1,-z*y); 63 } 64 else 65 { 66 x=read(),y=read(); 67 printf("%lld\n",(y*getsum(tree,y)-(x-1)*getsum(tree,x-1))-(getsum(tree1,y)-getsum(tree1,x-1))); 68 } 69 } 70 return 0; 71 }