链接:戳这里
思路:基础的懒散线段树练习 (水完这道就不水了)
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int n,q; ll a[400100],sum[400100],lazy[400100]; char s[10]; void build(int root,int l,int r){ if(l==r){ sum[root]=a[l]; return ; } int mid=(l+r)/2; build(root*2,l,mid); build(root*2+1,mid+1,r); sum[root]=sum[root*2]+sum[root*2+1]; } void pushdown(int root,int l){ if(lazy[root]){ lazy[root*2]+=lazy[root]; lazy[root*2+1]+=lazy[root]; sum[root*2]+=(ll)(l-l/2)*lazy[root]; sum[root*2+1]+=(ll)(l/2)*lazy[root]; lazy[root]=0; } } void update(int root,int l,int r,int x,int y,ll z){ if(l>=x && r<=y){ sum[root]+=(ll)(r-l+1)*z; lazy[root]+=z; return ; } pushdown(root,r-l+1); int mid=(l+r)/2; if(y<=mid) update(root*2,l,mid,x,y,z); else if(x>mid) update(root*2+1,mid+1,r,x,y,z); else { update(root*2,l,mid,x,mid,z); update(root*2+1,mid+1,r,mid+1,y,z); } sum[root]=sum[root*2]+sum[root*2+1]; } ll query(int root,int l,int r,int x,int y){ if(l>=x && r<=y){ ///cout<<"root="<<root<<" "<<sum[root]<<endl; return sum[root]; } pushdown(root,r-l+1); int mid=(l+r)/2; if(y<=mid) return query(root*2,l,mid,x,y); else if(x>mid) return query(root*2+1,mid+1,r,x,y); else { return query(root*2,l,mid,x,mid)+query(root*2+1,mid+1,r,mid+1,y); } } int main(){ while(scanf("%d%d",&n,&q)!=EOF){ mst(sum,0); mst(lazy,0); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); while(q--){ scanf("%s",s); int x,y; ll z; if(s[0]=='Q'){ scanf("%d%d",&x,&y); printf("%lld\n",query(1,1,n,x,y)); } else { scanf("%d%d%lld",&x,&y,&z); update(1,1,n,x,y,z); } } } return 0; }<strong> </strong>