2357 守墓人
提炼题目…
给定一个数列,给定若干个操作,查询修改等
线段树的模板题?
对线段树的模板题,只不过要多维护一个主墓的风水值,自从我学习了线段树,妈妈在也不用担心我的代码不过百了
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int SIZE=2e5+5;
int n,m;
int t[SIZE];
int lazys[SIZE],lazyb[SIZE];
int opt,x,y,z,mian;
inline void push_down(int p,int l,int r)//懒标记下传
{
if(lazyb[p])
{
int mid=(l+r)>>1;
lazyb[p*2]+=lazyb[p];lazyb[p*2+1]+=lazyb[p];
lazys[p*2]+=lazyb[p]*(mid-l+1);
lazys[p*2+1]+=lazyb[p]*(r-mid);
lazyb[p]=0;
}
}
inline void build(int p,int l,int r)
{
if(l==r)
{
cin>>t[p];//叶子节点直接输入
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p]=t[p*2]+t[p*2+1];//上传
return ;
}
inline void change(int p,int l,int r,int x,int y,int z)
{
if(x<=l&&y>=r)
{
lazyb[p]+=z;
lazys[p]+=z*(r-l+1);
return ;
}
push_down(p,l,r);
int mid=(l+r)>>1;
if(x<=mid) change(p*2,l,mid,x,y,z);
if(y>mid) change(p*2+1,mid+1,r,x,y,z);
t[p]=t[p*2]+t[p*2+1];
return ;
}
inline int query(int p,int l,int r,int x,int y)
{
if(x<=l&&y>=r) return t[p];//已查询到区间
push_down(p,l,r);
int ans=0;
int mid=(l+r)>>1;
if(x<=mid) ans+=query(p*2,l,mid,x,y);//递归查询区间
if(y>mid) ans+=query(p*2+1,mid+1,r,x,y);
return ans;
}
int main()
{
cin>>n>>m;
build(1,1,n);
for(int i=1;i<=m;i++)
{
cin>>opt;
if(opt==1)
{
cin>>x>>y>>z;
change(1,1,n,x,y,z);
continue;
}
if(opt==2)
{
cin>>x;
mian+=x;
continue;
}
if(opt==3)
{
cin>>x;
mian-=x;//mian计算主墓的风水
continue;
}
if(opt==4)
{
cin>>x>>y;
cout<<1ll*query(1,1,n,x,y)+(x==1)*mian<<endl;
continue;
}
if(opt==5)
{
cout<<1ll*query(1,1,n,1,1)+mian<<endl;
continue;
}
}
return 0;
}