由此题发现的一个常数优化
查看原帖
由此题发现的一个常数优化
779997
like_tis楼主2023/12/16 19:28
#include<cstdio>
#define ll long long
#define N 100005
using namespace std;
int n,q,m;
ll w[N*4],tagadd[N*4],tagmul[N*4],a[N];
void pushup(int u){
    w[u]=(w[u*2]+w[u*2+1])%m;
}
void build(int u,int l,int r){
    if(l==r){
        w[u]=a[l]%m;
        return;
    }
    int mid=(l+r)/2;
    build(u*2,l,mid);
    build(u*2+1,mid+1,r);
    pushup(u);
    tagmul[u]=1;
}
void maketag(int u,int len,ll x,int type){//1:mul,2:add
    if(type==1){
        tagadd[u]=(tagadd[u]*x)%m;
        tagmul[u]=(tagmul[u]*x)%m;
        w[u]=(w[u]*x)%m;
    }
    else{
        tagadd[u]=(tagadd[u]+x)%m;
        w[u]=(w[u]+len*x%m)%m;
    }
}
void pushdown(int u,int l,int r){
    int mid=(l+r)/2;
    maketag(u*2,mid-l+1,tagmul[u],1);
    maketag(u*2,mid-l+1,tagadd[u],2);
    maketag(u*2+1,r-mid,tagmul[u],1);
    maketag(u*2+1,r-mid,tagadd[u],2);
    tagmul[u]=1;
    tagadd[u]=0;
}
inline bool inrange(int l,int r,int L,int R){
    return(L<=l&&r<=R);
}
inline bool outofrange(int l,int r,int L,int R){
    return(l>R||r<L);
}
ll query(int u,int l,int r,int L,int R){
    if(inrange(l,r,L,R)) return w[u];
    else if(!outofrange(l,r,L,R)){
        int mid=(l+r)/2;
        pushdown(u,l,r);
        return (query(u*2,l,mid,L,R)+query(u*2+1,mid+1,r,L,R))%m;
    }
    else return 0;
}
void update(int u,int l,int r,int L,int R,ll x,int type){
    if(inrange(l,r,L,R)) maketag(u,r-l+1,x,type);
    else if(!outofrange(l,r,L,R)){
        int mid=(l+r)/2;
        pushdown(u,l,r);
        update(u*2,l,mid,L,R,x,type);
        update(u*2+1,mid+1,r,L,R,x,type);
        pushup(u);
    }
}
int main(){
    scanf("%d%d%d",&n,&q,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(q--){
        int type,x,y,k;
        scanf("%d%d%d",&type,&x,&y);
        if(type==1||type==2){
            scanf("%d",&k);
            update(1,1,n,x,y,k,type);
        }
        else{
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

m用变量1.37s

#include<cstdio>
#define ll long long
#define N 100005
using namespace std;
int n,q,p;
const int m=571373;
ll w[N*4],tagadd[N*4],tagmul[N*4],a[N];
void pushup(int u){
    w[u]=(w[u*2]+w[u*2+1])%m;
}
void build(int u,int l,int r){
    if(l==r){
        w[u]=a[l]%m;
        return;
    }
    int mid=(l+r)/2;
    build(u*2,l,mid);
    build(u*2+1,mid+1,r);
    pushup(u);
    tagmul[u]=1;
}
void maketag(int u,int len,ll x,int type){//1:mul,2:add
    if(type==1){
        tagadd[u]=(tagadd[u]*x)%m;
        tagmul[u]=(tagmul[u]*x)%m;
        w[u]=(w[u]*x)%m;
    }
    else{
        tagadd[u]=(tagadd[u]+x)%m;
        w[u]=(w[u]+len*x%m)%m;
    }
}
void pushdown(int u,int l,int r){
    int mid=(l+r)/2;
    maketag(u*2,mid-l+1,tagmul[u],1);
    maketag(u*2,mid-l+1,tagadd[u],2);
    maketag(u*2+1,r-mid,tagmul[u],1);
    maketag(u*2+1,r-mid,tagadd[u],2);
    tagmul[u]=1;
    tagadd[u]=0;
}
inline bool inrange(int l,int r,int L,int R){
    return(L<=l&&r<=R);
}
inline bool outofrange(int l,int r,int L,int R){
    return(l>R||r<L);
}
ll query(int u,int l,int r,int L,int R){
    if(inrange(l,r,L,R)) return w[u];
    else if(!outofrange(l,r,L,R)){
        int mid=(l+r)/2;
        pushdown(u,l,r);
        return (query(u*2,l,mid,L,R)+query(u*2+1,mid+1,r,L,R))%m;
    }
    else return 0;
}
void update(int u,int l,int r,int L,int R,ll x,int type){
    if(inrange(l,r,L,R)) maketag(u,r-l+1,x,type);
    else if(!outofrange(l,r,L,R)){
        int mid=(l+r)/2;
        pushdown(u,l,r);
        update(u*2,l,mid,L,R,x,type);
        update(u*2+1,mid+1,r,L,R,x,type);
        pushup(u);
    }
}
int main(){
    scanf("%d%d%d",&n,&q,&p);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(q--){
        int type,x,y,k;
        scanf("%d%d%d",&type,&x,&y);
        if(type==1||type==2){
            scanf("%d",&k);
            update(1,1,n,x,y,k,type);
        }
        else{
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

const int m 498ms

总结:模数用常量比变量快

2023/12/16 19:28
加载中...