• luogu P1438 无聊的数列


    思路

    区间(L)(R)内加等差数列
    已知首项为(K),公差为(D)
    那么每一位加的数值为

    [K+(i-L)*D(L<=i<=R) ]

    [K+i*D-L*D(L<=i<=R) ]

    [K-L*D+i*D(L<=i<=R) ]

    我们可以分别加一下(K-L*D)(i*D)
    前者可以算出来,直接区间加就可以
    后者的话,先维护一下([L,R])内的下标和
    结合律用一下,加上R*下标和就行了

    update

    修改的时候在区间([L,R])内的贡献为

    [(K-L*D)*(R-L+1)+sum_{L}^{R}*D ]

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #define ls rt<<1
    #define rs rt<<1|1
    #define ll long long
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int maxn = 1e5 + 7;
    int read() {
        int x = 0, f = 1; char s = getchar();
        for (; s < '0' || s > '9'; s = getchar()) if (s == '-') f = -1;
        for (; s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
        return x * f;
    }
    struct node {
    	int l,r,size;
    	ll ans,lazy1,tot,lazy2;
    }e[maxn<<2];
    int n,m,a[maxn];
    void pushup(int rt) {
    	e[rt].ans=e[ls].ans+e[rs].ans;
    }
    void pushdown(int rt) {
    	if(e[rt].lazy1) {
    		e[ls].ans+=e[ls].size*e[rt].lazy1;
    		e[rs].ans+=e[rs].size*e[rt].lazy1;
    		e[ls].lazy1+=e[rt].lazy1;
    		e[rs].lazy1+=e[rt].lazy1;
    		e[rt].lazy1=0;
    	}
    	if(e[rt].lazy2) {
    		e[ls].ans+=e[ls].tot*e[rt].lazy2;
    		e[rs].ans+=e[rs].tot*e[rt].lazy2;
    		e[ls].lazy2+=e[rt].lazy2;
    		e[rs].lazy2+=e[rt].lazy2;
    		e[rt].lazy2=0;
    	}
    }
    void build(int l,int r,int rt) {
    	e[rt].l=l,e[rt].r=r,e[rt].size=r-l+1;
    	if(l==r) {
    		e[rt].tot=l;
    		e[rt].ans=a[l];
    		return;
    	}
    	int mid=(e[rt].l+e[rt].r)>>1;
    	build(l,mid,ls);
    	build(mid+1,r,rs);
    	pushup(rt);
    	e[rt].tot=e[ls].tot+e[rs].tot;
    }
    void modfity_1(int L,int R,ll k,int rt) { // 区间加
    	if(L<=e[rt].l&&e[rt].r<=R) {
    		e[rt].ans+=k*e[rt].size;
    		e[rt].lazy1+=k;	
    		return;
    	}
    	pushdown(rt);
    	int mid=(e[rt].l+e[rt].r)>>1;
    	if(L<=mid) modfity_1(L,R,k,ls);
    	if(R>mid) modfity_1(L,R,k,rs);
    	pushup(rt);
    }
    void modfity_2(int L,int R,ll k,int rt) { // 区间i*k
    	if(L<=e[rt].l&&e[rt].r<=R) {
    		e[rt].ans+=k*e[rt].tot;
    		e[rt].lazy2+=k;
    		return;
    	}
    	pushdown(rt);
    	int mid=(e[rt].l+e[rt].r)>>1;
    	if(L<=mid) modfity_2(L,R,k,ls);
    	if(R>mid) modfity_2(L,R,k,rs);
    	pushup(rt);	
    }
    ll query(int L,int rt) {
    	if(e[rt].l==e[rt].r) {
    		return e[rt].ans;
    	}
    	pushdown(rt);
    	int mid=(e[rt].l+e[rt].r)>>1;
    	if(L<=mid) return query(L,ls);
    	else return query(L,rs);
    }
    int main() {
    	n=read(),m=read();
    	FOR(i,1,n) a[i]=read();
    	build(1,n,1);
    	FOR(i,1,m) {
    		int pd=read();
    		if(pd==1) {
    			int l=read(),r=read(),k=read(),d=read();
    			modfity_1(l,r,k-l*d,1);
    			modfity_2(l,r,d,1);
    		} else {
    			int x=read();
    			printf("%lld
    ",query(x,1));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    malloc
    排序算法学习笔记(三)-- 快速排序
    排序算法学习笔记(二)-- 归并排序
    排序算法学习笔记(一)-- 冒泡排序,选择排序,插入排序,希尔排序
    网络协议笔记
    域名和IP地址并用的理由
    WebSocket协议介绍
    Ajax概念
    共享密钥加密、公开密钥加密及HTTPS混合加密
    HTTP缺点
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9878736.html
Copyright © 2020-2023  润新知