JS陣列splice操作例項分析
阿新 • • 發佈:2020-11-19
題目連結
題目大意
給某個區間加上等差數列
解析
給原序列差分
然後加的操作只需要
在 \(l\) 出加上 \(k\)
在 \([l+1,r]\) 處加上 \(d\)
在 \(r+1\) 出加上 \(-[k+d*(r-l)]\) 消去影響
查詢及查 \([1,p]\) 的和
\(Code\)
#include<cstdio> #define LL long long #define ls (k << 1) #define rs (ls | 1) using namespace std; const int N = 1e5 + 5; int n , m , a[N]; struct segment{ LL sum , tag; }seg[N << 2]; void pushup(int k){seg[k].sum = seg[ls].sum + seg[rs].sum;} void pushdown(int l , int r , int k) { if (seg[k].tag == 0) return; int mid = (l + r) >> 1; seg[ls].sum += 1LL * (mid - l + 1) * seg[k].tag; seg[rs].sum += 1LL * (r - mid) * seg[k].tag; seg[ls].tag += seg[k].tag , seg[rs].tag += seg[k].tag; seg[k].tag = 0; } void build(int l , int r , int k) { if (l == r) { seg[k].sum = a[l] - a[l - 1] , seg[k].tag = 0; return; } int mid = (l + r) >> 1; build(l , mid , ls) , build(mid + 1 , r , rs); pushup(k); } void update(int l , int r , int k , int tl , int tr , int v) { if (tl > r || tr < l) return; if (tl <= l && r <= tr) { seg[k].sum += 1LL * (r - l + 1) * v , seg[k].tag += v; return; } pushdown(l , r , k); int mid = (l + r) >> 1; if (tl <= mid) update(l , mid , ls , tl , tr , v); if (tr > mid) update(mid + 1 , r , rs , tl , tr , v); pushup(k); } LL query(int l , int r , int k , int tl , int tr) { if (tl <= l && r <= tr) return seg[k].sum; pushdown(l , r , k); int mid = (l + r) >> 1; LL res = 0; if (tl <= mid) res += query(l , mid , ls , tl , tr); if (tr > mid) res += query(mid + 1 , r , rs , tl , tr); return res; } int main() { scanf("%d%d" , &n , &m); for(register int i = 1; i <= n; i++) scanf("%d" , &a[i]); build(1 , n , 1); int op , l , r , k , d; while (m--) { scanf("%d" , &op); if (op == 2) scanf("%d" , &k) , printf("%lld\n" , query(1 , n , 1 , 1 , k)); else { scanf("%d%d%d%d" , &l , &r , &k , &d); update(1 , n , 1 , l , l , k); update(1 , n , 1 , l + 1 , r , d); update(1 , n , 1 , r + 1 , r + 1 , -(k + 1LL * d * (r - l))); } } }