P1438 无聊的数列

题目

P1438 无聊的数列

做法

彻底觉得自己傻了,一眼题系列都看不出o(╥﹏╥)o

等差数列直接线段树维护一个差分数组就行了无聊的数列

My complete code

#include<bits/stdc++.h>
using namespace std;
typedef int LL;
const LL maxn=1e6;
LL n,nod,q,root;
LL lazy[maxn],son[maxn][2],sum[maxn],a[maxn];
inline void Pushdown(LL now,LL l,LL r){
	if(!lazy[now]) return;
	if(!son[now][0]) son[now][0]=++nod;
	if(!son[now][1]) son[now][1]=++nod;
	LL lc(son[now][0]),rc(son[now][1]);
	LL val(lazy[now]),mid(l+r>>1);
	lazy[lc]+=val,lazy[rc]+=val;
	sum[lc]+=(mid-l+1)*val,sum[rc]+=(r-mid)*val;
	lazy[now]=0;
}
void Add(LL &now,LL l,LL r,LL lt,LL rt,LL val){
	if(!now) now=++nod;
	if(lt<=l&&rt>=r){
		lazy[now]+=val,
		sum[now]+=(r-l+1)*val;
		return;
	}Pushdown(now,l,r);
	LL mid(l+r>>1);
	if(lt<=mid) Add(son[now][0],l,mid,lt,rt,val);
	if(rt>mid) Add(son[now][1],mid+1,r,lt,rt,val);
	sum[now]=sum[son[now][0]]+sum[son[now][1]];
}
LL Query(LL now,LL l,LL r,LL lt,LL rt){
	if(!now) return 0;
	if(lt<=l&&rt>=r) return sum[now];
	Pushdown(now,l,r);
	LL mid(l+r>>1),ret(0);
	if(lt<=mid) ret+=Query(son[now][0],l,mid,lt,rt);
	if(rt>mid) ret+=Query(son[now][1],mid+1,r,lt,rt);
	return ret;
}
int main(){
	cin>>n>>q;
	for(LL i=1;i<=n;++i) cin>>a[i];
	while(q--){
		LL op; cin>>op;
		if(op==1){
			LL l,r,k,d;
			cin>>l>>r>>k>>d;
			Add(root,1,n,l,l,k);
			if(r>l) Add(root,1,n,l+1,r,d);
			if(r!=n) Add(root,1,n,r+1,r+1,-(k+(r-l)*d));
		}else{
			LL p; cin>>p;
			cout<<Query(root,1,n,1,p)+a[p]<<endl;
		}
	}return 0;
}
原文地址:https://www.cnblogs.com/y2823774827y/p/10349484.html