社区讨论

线段树2求助

学术版参与者 2已保存回复 14

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
14 条
当前快照
1 份
快照标识符
@locxya21
此快照首次捕获于
2023/10/30 21:34
2 年前
此快照最后确认于
2023/11/05 07:56
2 年前
查看原帖
哭了调一天了,找不到错误,感觉写的没问题,样例都跑不出来 求助大佬们orz
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1;
struct Node{
    int l,r,sum,ad,cf;
}tree[4*maxn];
char s;
int n,m,p,x,y,k;
int a[maxn];
void pushdown(int i){
    //先更新子节点的值 
    tree[i<<1].sum=(tree[i<<1].sum*tree[i].cf+(tree[i<<1].r-tree[i<<1].l+1)*tree[i].ad)%p;
    tree[i<<1|1].sum=(tree[i<<1|1].sum*tree[i].cf+(tree[i<<1|1].r-tree[i<<1|1].l+1)*tree[i].ad)%p;
    //更新子节点的lazytag
    tree[i<<1].ad=(tree[i<<1].ad*tree[i].cf+tree[i<<1].ad)%p;
    tree[i<<1].cf=(tree[i<<1].cf*tree[i].cf)%p; 
    tree[i<<1|1].ad=(tree[i<<1|1].ad*tree[i].cf+tree[i<<1|1].ad)%p;
    tree[i<<1|1].cf=(tree[i<<1|1].cf*tree[i].cf)%p; 
    //父节点的lazytag还原
    tree[i].cf=1;
    tree[i].ad=0;
    return; 
} 
void build(int k,int l,int r){
    tree[k].cf=1;
    tree[k].ad=0;
    tree[k].l=l;
    tree[k].r=r;
    if(l==r){
        tree[k].sum=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p;
}
void change1(int i,int l,int r,int k){
    if(tree[i].l>=l&&tree[i].r<=r){
        tree[i].sum=(tree[i].sum*k)%p;
        tree[i].ad=(tree[i].ad*k)%p;
        tree[i].cf=(tree[i].cf*k)%p;
        return;
    }
    pushdown(i);
    if(tree[i<<1].r>=l)change1(i<<1,l,r,k);
    if(tree[i<<1|1].l<=r)change1(i<<1|1,l,r,k);
    tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p; 
    return;
}
void change2(int i,int l,int r,int k){
    if(tree[i].l>=l&&tree[i].r<=r){
        tree[i].ad=(tree[i].ad+k)%p;
        tree[i].sum=(tree[i].sum+k*(tree[i].r-tree[i].l+1))%p;
        return;
    }
    pushdown(i);
    if(tree[i<<1].r>=l)change1(i<<1,l,r,k);
    if(tree[i<<1|1].l<=r)change1(i<<1|1,l,r,k);
    tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%p; 
    return;
}
int find(int i,int l,int r){
    if(tree[i].l>=l&&tree[i].r<=r)return tree[i].sum;
    pushdown(i);
    int ans=0;
    if(l<=tree[i*2].r)ans=(ans+find(i*2,l,r))%p;
    if(r>=tree[i*2+1].l)ans=(ans+find(i*2+1,l,r))%p;
    return ans%p;
}
int main(){
    cin>>n>>m>>p;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>s;
        if(s=='1'){
            cin>>x>>y>>k;
            change1(1,x,y,k);
        }
        if(s=='2'){
            cin>>x>>y>>k;
            change2(1,x,y,k);
        }
        if(s=='3'){
            cin>>x>>y;
            cout<<(find(1,x,y))%p<<endl;
        }
    }
    return 0;
}

回复

14 条回复,欢迎继续交流。

正在加载回复...