传送门:https://www.luogu.org/problem/P1438
线段树板子题,
真的裸,
数学题真好磕
如果看到加上等差数列还想不到差分的话我也没话可说了……
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 100050; 4 typedef long long ll; 5 #define fr(i,n) for(int i = 1; i <= n; i++) 6 #define pr(n) printf("%d ",n) 7 inline int read() { 8 char c = getchar(); 9 int x = 0, f = 1; 10 while(c < '0' || c > '9') { 11 if(c == '-') f = -1; 12 c = getchar(); 13 } 14 while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); 15 return x * f; 16 } 17 int n,m; 18 int s[N], tag[N<<2]; 19 int sum[N<<2]; 20 21 void pushup(int u) { sum[u] = sum[u << 1] + sum[u << 1 | 1]; } 22 23 void buildTree(int u, int uL, int uR) 24 { 25 if(uL == uR) { 26 scanf("%lld",&sum[u]); 27 return ; 28 } 29 int mid = (uL + uR) >> 1; 30 buildTree(u << 1, uL,mid); 31 buildTree(u << 1 | 1, mid + 1,uR); 32 pushup(u); 33 } 34 35 void update(int u, int uL, int uR, int mx) 36 { 37 tag[u] += mx; 38 sum[u] += (ll)(uR - uL + 1) * mx; 39 } 40 41 void pushdown(int u, int uL, int uR) 42 { 43 if(tag[u]){ 44 int mid = (uL + uR) >> 1; 45 update(u << 1, uL, mid, tag[u]); 46 update(u << 1|1, mid + 1,uR, tag[u]); 47 tag[u] = 0; 48 } 49 } 50 51 void modify(int u, int uL, int uR, int mL, int mR, int mx) 52 { 53 if(mL <= uL && mR >= uR) { 54 update(u,uL,uR,mx); 55 return; 56 } 57 pushdown(u,uL,uR); 58 int mid = (uL + uR) >> 1; 59 if(mL <= mid) modify(u << 1, uL, mid, mL, mR, mx); 60 if(mid < mR) modify(u << 1 | 1, mid + 1, uR, mL,mR, mx); 61 pushup(u); 62 } 63 64 ll query(int u, int uL, int uR, int mL, int mR) 65 { 66 if(mL <= uL && mR >= uR) return sum[u]; 67 pushdown(u, uL, uR); 68 int mid = (uL + uR) >> 1; 69 ll ans = 0; 70 if(mL <= mid) ans += query(u << 1, uL, mid, mL, mR); 71 if(mid < mR) ans += query(u << 1 | 1, mid + 1, uR, mL, mR); 72 return ans; 73 } 74 //------------------------------------------------以上是板子---------------------------------- 75 int main() 76 { 77 int l,r,opt,k,d,n,m,aim; 78 n = read();m = read(); 79 fr(i,n) s[i] = read(); 80 while(m--){ 81 opt = read(); 82 if(opt == 1){ //1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上。 83 l = read(),r = read(),k = read(),d = read(); 84 modify(1,1,n,l,l,k); 85 if(r > l) modify(1,1,n,l+1,r,d); 86 int N = r - l + 1; 87 if(r != n) modify(1,1,n,r+1,r+1,-(k+(N-1)*d)); 88 } 89 else { 90 aim = read(); 91 pr(s[aim] + query(1,1,n,1,aim)); 92 } 93 } 94 return 0; 95 }