线段树
2024-06-30 09:57:50
发布于:上海
16阅读
0回复
0点赞
显然是线段树的板子。单点操作用区间模拟即可。但是:
开 long long!
一切可能要开 long long 的地方都要开 long long,比如快读,初始数组,快写(警示后人)。
#include <cstdoi>
#include <algorithm>
using namespace std;
#define MAXN 200000
#define m(l,r) ((l+r)>>1)
#define ls(k) (k<<1)
#define rs(k) ((k<<1)|1)
struct node{
int l,r;
long long dat,tag;
}t[4*MAXN+5];
long long a[MAXN+1];
void build(int p, long long l, long long r){
t[p].l=l;
t[p].r=r;
t[p].tag=0;
if(l==r){t[p].dat=a[l]; return;}
int mid=m(l,r);
build(ls(p),l,mid);
build(rs(p),mid+1,r);
t[p].dat=t[ls(p)].dat+t[rs(p)].dat;
}
inline void down(int p){
if(t[p].tag){
t[ls(p)].dat+=t[p].tag*(t[ls(p)].r-t[ls(p)].l+1);
t[rs(p)].dat+=t[p].tag*(t[rs(p)].r-t[rs(p)].l+1);
t[ls(p)].tag+=t[p].tag;
t[rs(p)].tag+=t[p].tag;
t[p].tag=0;
}
}
void change(int p,long long x,long long y,long long z){
if(x<=t[p].l && y>=t[p].r){
t[p].dat+=z*(t[p].r-t[p].l+1);
t[p].tag+=z;
return;
}
down(p);
long long mid=m(t[p].l,t[p].r);
if(x<=mid) change(ls(p),x,y,z);
if(y>mid) change(rs(p),x,y,z);
t[p].dat=t[ls(p)].dat+t[rs(p)].dat;
}
long long ask(int p,long long x,long long y){
if(x<=t[p].l && y>=t[p].r) return t[p].dat;
down(p);
long long mid=m(t[p].l,t[p].r);
long long ans=0;
if(x<=mid) ans+=ask(ls(p),x,y);
if(y>mid) ans+=ask(rs(p),x,y);
return ans;
}
inline long long read(){
long long x=0;
bool w=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=='-'&&(w=1),ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return w?-x:x;
}
void write(long long x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar((x%10)|48);
}
int main(){
int n=read(),f=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1;i<=f;i++){
int op,l,r;long long k;
op=read();
switch(op){
case 1:{
l=read(),r=read(),k=read();
change(1,l,r,k);
break;
}
case 2:{
k=read();
change(1,1,1,k);
break;
}
case 3:{
k=read();
change(1,1,1,-k);
break;
}
case 4:{
l=read(),r=read();
write(ask(1,l,r));putchar(10);
break;
}
case 5:{
write(ask(1,1,1));putchar(10);
break;
}
}
}
return O;
}
完结撒花~
这里空空如也
有帮助,赞一个