1 solutions

  • 1
    @ 2024-12-24 19:39:36

    聪明的人看这个讨论就已经不用往下看了。

    题意

    不多赘述。主要是我不会概括

    思路

    回想一下树状数组模板 2,我们既然可以用树状数组维护差分数组,那也可以用线段树维护差分数组。

    把样例变成差分数组就是:

    1 1 1 1 1 |1 2 3 4 5
        ↓     |    ↓
    1 2 3 3 -4|1 3 6 9 5
    

    查询时再差前缀和就行了。

    代码

    不开龙龙见祖宗——hmz

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 1e5 + 5;
    int n,m;
    int a[N],d[4 * N],b[4 * N];
    void pd(int l,int r,int p){
    	int mid = l + (r - l >> 1);
    	d[p * 2] += b[p] * (mid - l + 1),d[p * 2 + 1] += b[p] * (r - mid);
    	b[p * 2] += b[p],b[p * 2 + 1] += b[p];
    	b[p] = 0;
    }
    void build(int l,int r,int p){
    	if (l == r){
    //		printf("%d:%d\n",l,p);
    		d[p] = a[l];
    		return ;
    	}
    	int mid = l + (r - l >> 1);
    	build(l,mid,p * 2);
    	build(mid + 1,r,p * 2 + 1);
    	d[p] = d[p * 2] + d[p * 2 + 1];
    }
    void add(int tl,int tr,int x,int l,int r,int p){
    	if (tl <= l && r <= tr){
    		d[p] += x * (r - l + 1);
    		b[p] += x;
    //		printf("%d %d\n",p,d[p]);
    		return ;
    	}
    	pd(l,r,p);
    	int mid = l + (r - l >> 1);
    	if (tl <= mid)	add(tl,tr,x,l,mid,p * 2);
    	if (mid < tr)	add(tl,tr,x,mid + 1,r,p * 2 + 1);
    	d[p] = d[p * 2] + d[p * 2 + 1];
    //	printf("%d %d\n",p,d[p]);
    }
    int query(int i,int l,int r,int p){
    	if (r <= i)	return d[p];
    	pd(l,r,p);
    	int mid = l + (r - l >> 1);
    	int sum = query(i,l,mid,p * 2);
    	if (mid < i)	sum += query(i,mid + 1,r,p * 2 + 1);
    	return sum;
    }
    void add(int tl,int tr,int k,int d){
    	add(tl,tl,k,1,n,1);
    	if (tl < tr)	add(tl + 1,tr,d,1,n,1);
    	if (tr < n)	add(tr + 1,tr + 1,-(k + d * (tr - tl)),1,n,1);
    }
    signed main(int argc, char **argv){
    	cin >> n >> m;
    	for (int i = 1;i <= n;i++){
    		cin >> a[i];
    	}
    	for (int i = n;i > 0;i--){
    		a[i] = a[i] - a[i - 1];
    	}
    	build(1,n,1);
    	while (m--){
    		int op;
    		cin >> op;
    		if (op == 1){
    			int l,r,k,d;
    			cin >> l >> r >> k >> d;
    			add(l,r,k,d);
    		}else{
    			int p;
    			cin >> p;
    			printf("%lld\n",query(p,1,n,1));
    		}
    	}
    	return 0;
    }
    
    
    • 1

    Information

    ID
    293
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    8
    Tags
    # Submissions
    40
    Accepted
    6
    Uploaded By