思路不太一样,样例没过,求大佬帮忙
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
const int N=1e5+12;
long long n,q,m,floor_;
long long a[N],tree[N<<2],tag[N<<2];
long long lchild(long long p){
return p<<1;
}
long long rchild(long long p){
return p<<1|1;
}
void push_up(long long p){
tree[p]=tree[lchild(p)]+tree[rchild(p)];
}
void build(long long p,long long pl,long long pr){
tag[p]=0;
if (pl==pr){
tree[p]=a[pl];
return ;
}
long long mid=(pl+pr)>>1;
build(lchild(p),pl,mid); //构建左子树
build(rchild(p),mid+1,pr); //构建右子树
push_up(p); //
}
//void gettag(long long L,long long R,long long k){
// floor_=ceil(log2(n))
// int num=pow(2,floor_-1)-1;//该层上面的数的个数
// int rest=n-num; //该层的剩余个数
// int p=num+L;
// while(p<=num+R){
// if (p==rest+num) {
// floor_--;
// num=pow(2,floor_)-1;
//
// }
//
// }
// for (int i=num+L;i<=num+R && i<=num+rest;i++){
// tag[i]=tree[i]*(k-1);
// cout<<i<<" ";
// cout<<tag[i]<<endl;
// tag[i]%=m;
// }
// for (int i=)
// return ;
//}
void gettag(long long L,long long R,long long k,long long now,long long cnt){
// if (lchild(now)) gettag(L,R,k,lchild(now),cnt);
if (lchild(now)>n && rchild(now)>n) {
return ;
}
if (lchild(now)) gettag(L,R,k,lchild(now),cnt);
if (lchild(now)>n && rchild(now)>n) {
++cnt;
if (L<=cnt && cnt<=R) tag[now]+=(tree[now]*(k-1));
cout<<now<<" "<<(tree[now]*(k))<<endl;
return ;
}
if (rchild(now)) gettag(L,R,k,rchild(now),cnt);
return ;
}
void addtag(long long p,long long pl,long long pr,long long d){ //d为未修改值
tag[p]+=d; //打上标记
tree[p]+= (pr-pl+1)*d; //更新tree
}
//更新子节点(若有tag标记,则更新)
void push_down(long long p,long long pl,long long pr){
if (tag[p]) {
long long mid=(pl+pr)>>1;
addtag(lchild(p),pl,mid,tag[p]);//将tag标记传给左子树
addtag(rchild(p),mid+1,pr,tag[p]);//将tag标记传给右子树
tag[p]=0;//tag标记被传走,归零
}
}
//L:左端点 R:右端点 p:线段位置 pl、pr:线段区间 d:修改值
void updata(long long L,long long R,long long p,long long pl,long long pr,long long d){
if (L<=pl && pr<=R){
addtag(p,pl,pr,d);
return ;
}
push_down(p,pl,pr); //如果不能覆盖,就将tag传递给子树
long long mid=(pl+pr)>>1;
if (L<=mid) updata(L,R,lchild(p),pl,mid,d);
if (R>mid) updata(L,R,rchild(p),mid+1,pr,d);
push_up(p);//修改之后传参
}
long long query(long long L,long long R,long long p,long long pl,long long pr){
if (L<=pl && pr<=R) return tree[p];
push_down(p,pl,pr);//先查看是否有tag标记并更新有标记的tag的节点的子节点
long long ret=0;
long long mid=(pl+pr)>>1;
if (L<=mid) ret+=query(L,R,lchild(p),pl,mid),ret%=m;
if (R>mid) ret+=query(L,R,rchild(p),mid+1,pr),ret%=m;
return ret%m;
}
int main(){
scanf("%lld %lld %lld",&n,&q,&m);
floor_=ceil(log2(n));
for (int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
while(q--){
long long op,L,R,k;
scanf("%lld",&op);
if (op==1) {
scanf("%lld %lld %lld",&L,&R,&k);
// updata(L,R,1,1,n,k);
// cout<<1;
gettag(L,R,k,1,0);
updata(L,R,1,1,n,k);
}
else if (op==2){
scanf("%lld %lld %lld",&L,&R,&k);
updata(L,R,1,1,n,k);
}
else {
scanf("%lld %lld",&L,&R);
printf("%lld\n",query(L,R,1,1,n));
}
}
return 0;
}