1 条题解

  • 0
    @ 2023-2-18 11:32:23

    写这篇解主要是为了记录一个小技巧:

    区间加一个等差数列,可以用差分:

    设差分序列为 aa,首项为 ss,末项为 ee,公差为 dd,要在 [l,r][l, r] 这段区间加上这个等差数列。

    ala_l 加上 ss,在 al+1,al+2,,ara_{l+1}, a_{l+2}, \cdots, a_r 加上 dd,最后在 ar+1a_{r+1} 减去 ee 即可。

    在这道题中,可以用线段树维护这个差分序列,求第 pp 个数是多少时,答案就是 i=1pai\sum_{i=1}^p a_i

    以及,小心越界,开 longlong。

    #include <bits/stdc++.h>
    using namespace std;
    int n, m;
    long long a[100005], tree[400005], lazy[400005];
    void pushdown(int rt, int l, int r) {
    	int m = (l+r)>>1;
    	tree[rt<<1] += (m-l+1)*lazy[rt];
    	tree[rt<<1|1] += (r-m)*lazy[rt];
    	lazy[rt<<1] += lazy[rt];
    	lazy[rt<<1|1] += lazy[rt]; 
    	lazy[rt] = 0;
    }
    void build(int rt, int l = 1, int r = n) {
    	if (l == r) {
    		tree[rt] = a[l]-a[l-1];
    		return;
    	}
    	int m = (l+r)>>1;
    	build(rt<<1, l, m);
    	build(rt<<1|1, m+1, r);
    	tree[rt] = tree[rt<<1]+tree[rt<<1|1];
    }
    long long query(int rt, int x, int y, int l = 1, int r = n) {
    	if (l >= x && r <= y) return tree[rt];
    	pushdown(rt, l, r);
    	int m = (l+r)>>1;
    	long long ans = 0;
    	if (x <= m)	ans += query(rt<<1, x, y, l, m);
    	if (m < y) ans += query(rt<<1|1, x, y, m+1, r);
    	return ans;
    }
    void modify(int rt, long long val, int x, int y, int l = 1, int r = n) {
    	if (l >= x && r <= y) {
    		tree[rt] += (r-l+1)*val;
    		lazy[rt] += val;
    		return ;
    	}
    	pushdown(rt, l, r);
    	int m = (l+r)>>1;
    	if (x <= m) modify(rt<<1, val, x, y, l, m);
    	if (m < y) modify(rt<<1|1, val, x, y, m+1, r);
    	tree[rt] = tree[rt<<1]+tree[rt<<1|1];
    }
    int main()
    {
    	cin >> n >> m;
    	for (int i = 1; i <= n; i++)
    		cin >> a[i];
    	build(1);
    	while (m--) {
    		int opt;
    		cin >> opt;
    		if (opt == 1) {
    			int l, r;
    			long long K, D;
    			cin >> l >> r >> K >> D;
    			modify(1, K, l, l);
    			if (l+1 <= n)
    				modify(1, D, l+1, r);
    			if (r+1 <= n)
    				modify(1, -(K+(r-l)*D), r+1, r+1);
    		} else {
    			int p;
    			cin >> p;
    			cout << query(1, 1, p) << endl;
    		}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    438
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    15
    已通过
    2
    上传者