想试试用动态开点写,30pts,样例过不了。 感谢大佬帮忙。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,cnt,root;
struct node{
int l,r,w,f;
} tree[2*100000+1];
int a[100001];
inline int read(){
char c; int x=0,f=1; c=getchar();
while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
return x*f;
}
inline void push_up(int k){
tree[k].w=tree[tree[k].l].w+tree[tree[k].r].w;
}
inline int build(){
tree[++cnt].w=0;
tree[cnt].f=0;
tree[cnt].l=0;
tree[cnt].r=0;
return cnt;
}
inline void push_down(int k,int l,int r){
tree[tree[k].l].w+=(tree[tree[k].l].r-tree[tree[k].l].l+1)*tree[k].f;
tree[tree[k].r].w+=(tree[tree[k].r].r-tree[tree[k].r].l+1)*tree[k].f;
tree[tree[k].l].f+=tree[k].f;
tree[tree[k].r].f+=tree[k].f;
tree[k].f=0;
}
inline void insert(int l,int r,int k,int ind,int x){
if(l==r){
tree[k].w=x; return;
}
int mid=(l+r)>>1;
if(ind<=mid){
if(!tree[k].l) tree[k].l=build();
insert(l,mid,tree[k].l,ind,x);
}
else{
if(!tree[k].r) tree[k].r=build();
insert(mid+1,r,tree[k].r,ind,x);
}
push_up(k);
}
inline int ask_interval(int k,int l,int r,int a,int b){
if(l>=a&&r<=b){
return tree[k].w;
}
if(tree[k].f) push_down(k,l,r);
int mid=(l+r)>>1,ans=0;;
if(a<=mid) ans+=ask_interval(tree[k].l,l,mid,a,b);
if(b>mid) ans+=ask_interval(tree[k].r,mid+1,r,a,b);
return ans;
}
inline void change_interval(int k,int l,int r,int a,int b,int y){
if(l>=a&&r<=b){
tree[k].w+=(tree[k].r-tree[k].l+1)*y;
tree[k].f+=y;
return ;
}
if(tree[k].f) push_down(k,l,r);
int mid=(l+r)>>1;
if(a<=mid){
if(!tree[k].l) tree[k].l=build();
change_interval(tree[k].l,l,mid,a,b,y);
}
if(b>mid) {
if(!tree[k].r) tree[k].r=build();
change_interval(tree[k].r,mid+1,r,a,b,y);
}
push_up(k);
}
signed main()
{
n=read();
m=read();
root=build();
for(int i=1;i<=n;i++){
a[i]=read();
insert(1,n,root,i,a[i]);
}
while(m--){
int opt=read();
if(opt==1){
int a=read(),b=read(),y=read();
change_interval(1,1,n,a,b,y);
}
if(opt==2){
int a=read(),b=read();
printf("%lld\n",ask_interval(1,1,n,a,b));
}
}
return 0;
}
```cpp