分析:
如果普通暴力做 肯定过不了 那么我们就要考虑 更高效的 数据结构
比如分块 线段树 树状数组等
然后就可以用 线段树过了 要加
l
a
z
y
lazy
lazy标记 比分块快
200
m
s
200ms
200ms
至于主墓的风水和 题目说它是编号
1
1
1 那其实就是区间
[
1
,
1
]
[1,1]
[1,1]的风水和了 就不用专门记录了
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<bitset>
//#pragma GCC optimize(2)
#define reg register
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int N=2e5+5;
ll n,m,a[N],ans[N*4],lazy[N*4],kd,l,r,k;
void up(ll x){ans[x]=ans[x<<1]+ans[x<<1|1];}
void val(ll i,ll l,ll r,ll k){
lazy[i]=lazy[i]+k;
ans[i]=ans[i]+(r-l+1)*k;
}
void down(ll i,ll l,ll r){
ll mid=(l+r)>>1;
val(i<<1,l,mid,lazy[i]);
val(i<<1|1,mid+1,r,lazy[i]);
lazy[i]=0;
}
void build(ll i,ll l,ll r)
{
lazy[i]=0;
if(l==r){
ans[i]=a[l];
return;
}
ll mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
up(i);
}
void update(ll a,ll b,ll l,ll r,ll i,ll k)
{
if(a<=l&&r<=b)
{
ans[i]+=(r-l+1)*k;
lazy[i]+=k;
return;
}
down(i,l,r);
ll mid=(l+r)>>1;
if(a<=mid) update(a,b,l,mid,i<<1,k);
if(b>mid) update(a,b,mid+1,r,i<<1|1,k);
up(i);
}
ll query(ll a,ll b,ll l,ll r,ll i)
{
ll res=0;
if(a<=l&&r<=b) return ans[i];
ll mid=(l+r)>>1;
down(i,l,r);
if(a<=mid) res+=query(a,b,l,mid,i<<1);
if(b>mid) res+=query(a,b,mid+1,r,i<<1|1);
return res;
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--)
{
scanf("%lld",&kd);
if(kd==1){
scanf("%lld%lld%lld",&l,&r,&k);
update(l,r,1,n,1,k);
}
if(kd==2){
scanf("%lld",&k);
update(1,1,1,n,1,k);
}
if(kd==3){
scanf("%lld",&k);
update(1,1,1,n,1,-k);
}
if(kd==4){
scanf("%lld%lld",&l,&r);
printf("%lld\n",query(l,r,1,n,1));
}
if(kd==5) printf("%lld\n",query(1,1,1,n,1));
}
return 0;
}