社区讨论

求教大佬,#2#9#10WA到想吐了。。

P3373【模板】线段树 2参与者 3已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mi6tp84f
此快照首次捕获于
2025/11/20 10:39
4 个月前
此快照最后确认于
2025/11/20 10:39
4 个月前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
long long num[100010],n,k,tree[400040],tag[400040],tag2[400040],p;
void Pushup(long long rt)
{
    tree[rt]=tree[rt*2]+tree[rt*2+1];
    tree[rt]%=p;
}
void build(long long l,long long r,long long now)
{
    if(l==r)
    {
        tree[now]=num[l];
        return;
    }
    long long m=(l+r)/2;
    build(l,m,now*2);
    build(m+1,r,now*2+1);
    Pushup(now);
}
void up2(int l,int r,int c,int now,bool pls)
{
    if(pls){
        tree[now]+=c*(r-l+1)%p;
        tree[now]%=p;
        if(l==r)return;
        tag[now]+=c;
        tag[now]%=p;
        return;
    }
    else{
        tree[now]*=c;
        tree[now]%=p;
        if(l==r)return;
        tag[now]*=c;
        tag2[now]*=c;
        tag[now]%=p;
        tag2[now]%=p;
        return;
    }
}
void update(long long L,long long R,long long l,long long r,long long c,long long now)
{
    long long m=(l+r)/2;
    if(tag2[now]!=1){
        up2(l,m,tag2[now],now<<1,0);
        up2(m+1,r,tag2[now],now<<1|1,0);
        tag2[now]=1;
    }
    if(tag[now]){
        up2(l,m,tag[now],now<<1,1);
        up2(m+1,r,tag[now],now<<1|1,1);
        tag[now]=0;
    }
    if(L<=l&&r<=R)
    {
        tree[now]+=c*(r-l+1)%p;
        tree[now]%=p;
        if(l==r)return;
        tag[now]+=c;
        tag[now]%=p;
        return;
    }
    if(L <= m) update(L,R,l,m,c,now*2);
    if(m < R) update(L,R,m+1,r,c,now*2+1);
    Pushup(now);
}
void updateb(long long L,long long R,long long l,long long r,long long c,long long now)
{
    long long m=(l+r)/2;
    if(tag2[now]!=1){
        up2(l,m,tag2[now],now<<1,0);
        up2(m+1,r,tag2[now],now<<1|1,0);
        tag2[now]=1;
    }
    if(tag[now]){
        up2(l,m,tag[now],now<<1,1);
        up2(m+1,r,tag[now],now<<1|1,1);
        tag[now]=0;
    }
    if(L<=l&&r<=R)
    {
        tree[now]*=c%p;
        tree[now]%=p;
        if(l==r)return;
        tag[now]*=c%p;
        tag[now]%=p;
        tag2[now]*=c%p;
        tag2[now]%=p;
        return;
    }
    if(L <= m) updateb(L,R,l,m,c,now*2);
    if(m < R) updateb(L,R,m+1,r,c,now*2+1);
    Pushup(now);
}
long long query(long long L,long long R,long long l,long long r,long long now)
{
    /*if(tag[now]){
        up2(l,m,tag[now],now<<1);
        up2(m+1,r,tag[now],now<<1|1);
        tree[now]=tree[now<<1]+tree[now<<1|1];
        tag[now]=0;
    }*/
    if(L <= l && R >= r)
    {
        return tree[now];
    }
    long long ans=0,m=(l+r)/2;
    if(tag2[now]!=1){
        up2(l,m,tag2[now],now<<1,0);
        up2(m+1,r,tag2[now],now<<1|1,0);
        //tree[now]=tree[now<<1]+tree[now<<1|1];
        //tree[now]%=p;
        tag2[now]=1;
    }
    if(tag[now]){
        up2(l,m,tag[now],now<<1,1);
        up2(m+1,r,tag[now],now<<1|1,1);
        //tree[now]=tree[now<<1]+tree[now<<1|1];
        //tree[now]%=p;
        tag[now]=0;
    }
    if(L <= m) ans+=query(L,R,l,m,now*2);
    //ans%=p;
    if(R > m) ans+=query(L,R,m+1,r,now*2+1);
    return ans;
}
int main()
{
    cin >> n >> k >> p;
    for(int i = 1;i <=4*n;i++){
        tag2[i]=1;
    }
    for(long long i = 1;i <= n;i++){
        scanf("%lld",&num[i]);
    }
    long long flag=1,a,b,c;
    build(1,n,1);
    /*for(long long i = 0;i < 20;i++){
                cout << tree[i] << ' ';
            }
            cout << endl;*/
    for(long long i = 0;i < k;i++){
        cin >> flag;
        if(flag==1){
            scanf("%lld%lld%lld",&a,&b,&c);
            updateb(a,b,1,n,c,1);
            /*for(long long i = 0;i < 20;i++){
                cout << tree[i] << ' ';
            }
            cout << endl;*/
        }
        else if(flag==2){
            scanf("%lld%lld%lld",&a,&b,&c);
            update(a,b,1,n,c,1);
        }
        else{
            scanf("%lld%lld",&a,&b);
            cout << query(a,b,1,n,1)%p << endl;
        }
    }
    /*for(long long i = 0;i < 20;i++){
        cout << tree[i] << ' ';
    }*/
    return 0;
}
代码有点丑...还请大佬原谅 确实不知道该怎么改了

回复

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

正在加载回复...