这道题和poj2777是一模一样的 模版都是一样的 使用lazy思想 这个思想我也不太好解释 其实就是
核心:
先懒着
对 没错 就是先懒着 updata的时候 不更新到叶子节点 先保存之后就放着不管
当你需要这个区间的时候再次展开 这样其实有的区间原来展开了 但是你不查询并没有什么用
所以这里的”先懒着”思想 很好的利用了题目的已知条件 只对需要查询的区间展开
美丽的姿势 避免了tle的悲剧
#include<cstdio>
//#include<time.h>
#include<stdlib.h>
const int maxn=1e5+5;
typedef long long ll;
struct note{
int l,r;
ll sum,cover;
}a[(maxn<<2)];
void init_(int i,int l,int r){
a[i].l=l;
a[i].r=r;
a[i].sum=0;
a[i].cover=0;
if(l==r){
scanf("%lld",&a[i].sum);return ;
}
int mid_=(l+r)>>1;
init_(i<<1,l,mid_);
init_(i<<1 |1,mid_+1,r);
a[i].sum=a[i<<1].sum+a[i<<1 |1].sum;
}
void scanf_(char& t){
while((t=getchar())&&(t!='Q'&&t!='C')){}
}
ll calc(int x,int y,int judge){
ll sum_=(ll)(y-x+1);
ll mid=sum_>>1;
if(!judge)return sum_-mid;
return mid;
}
ll getsum(int i,int start,int aim){
if(a[i].l==start&&a[i].r==aim)
return a[i].sum;
if(a[i].cover){
a[i<<1].cover+=a[i].cover;
a[i<<1 |1].cover+=a[i].cover;
a[i<<1].sum+=a[i].cover*calc(a[i].l,a[i].r,0);
a[i<<1 |1].sum+=a[i].cover*calc(a[i].l,a[i].r,1);
a[i].cover=0;
}
int mid=(a[i].l+a[i].r)>>1;
if(start>mid)return getsum(i<<1 |1,start,aim);
else if(aim<=mid)return getsum(i<<1,start,aim);
else return getsum(i<<1,start,mid)+getsum(i<<1 |1,mid+1,aim);
}
void updata(int i,int start,int aim,int data){
if(a[i].l==start&&a[i].r==aim){
a[i].cover+=data;
a[i].sum+=(data*(aim-start+1));
return;
}
if(a[i].cover){
a[i<<1].cover+=a[i].cover;
a[i<<1 |1].cover+=a[i].cover;
a[i<<1].sum+=(a[i].cover*calc(a[i].l,a[i].r,0));
a[i<<1 |1].sum+=(a[i].cover*calc(a[i].l,a[i].r,1));
a[i].cover=0;
}
int mid=(a[i].l+a[i].r)>>1;
if(start>mid){
updata(i<<1 |1,start,aim,data);
}
else if(aim<=mid) updata(i<<1,start,aim,data);
else{
updata(i<<1,start,mid,data);
updata(i<<1 |1,mid+1,aim,data);
}
a[i].sum=a[i<<1].sum+a[i<<1 |1].sum;
}
int main(){
int n,m;
// freopen("in6.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=-1){
init_(1,1,n);
while(m--){
char t;
int x,y,z;
scanf_(t);
if(t=='Q'){
scanf("%d%d",&x,&y);
printf("%lld\n",getsum(1,x,y));
}
else{
scanf("%d%d%d",&x,&y,&z);
updata(1,x,y,z);
}
}
}
return 0;
}
//const int coun=0x3fffffff;
// clock_t t1,t2,t3;
// m=10;
// while(m--){
// t1=clock();
// for(int i=0;i<coun;i++){
// int x=i,y=i+1;
// if(x&1){
// x=y;
// }
// if(!(x^y)){
//
// }
// }
// t2=clock();
// for(int i=0;i<coun;i++){
// int x=i,y=i+1;
// if(x%2==1){
// x=y;
// }
// if(x==y){
//
// }
// }
// t3=clock();
// printf("%.3lf %.3lf\n",(t2-t1)/1000.0,(t3-t2)/1000.0);
// }