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;
}