CF438D The Child and Sequence 线段树水题

CF438D The Child and Sequence 线段树水题

链接

取模操作只需要暴力做就可以。我们只需要维护其最大值然后判断模数是否大于最大值,如果大于,那么就不用取模了,否则直接往下做。注意到每一个数最多被取模 \(\log\) 次,复杂度最多不超过 \(n\log^210^9\)

要注意不加 pushup 尽量不要加,因为如果,pushup 叶子节点就完蛋了。

\(4\) 秒还是可以过的。

#include<bits/stdc++.h>
#define dd double
#define ld long double
#define ll long long
#define int long long
#define uint unsigned int
#define ull unsigned long long
#define N 100010
#define M number
using namespace std;

const int INF=0x3f3f3f3f;

template<typename T> inline void read(T &x) {
    x=0; int f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    x*=f;
}

template<typename T> inline T Max(T a,T b){
    return a<b?b:a;
}

int n,m,a[N];

struct node{
    int sum,maxx;
};

struct ST{
    node p[N<<4];
    inline void pushup(int k){
        p[k].sum=p[k*2].sum+p[k*2+1].sum;
        p[k].maxx=Max(p[k*2].maxx,p[k*2+1].maxx);
    }
    inline void build(int k,int l,int r){
        if(l==r){p[k].sum=a[l];p[k].maxx=a[l];return;}
        int mid=(l+r)>>1;
        build(k*2,l,mid);build(k*2+1,mid+1,r);
        pushup(k);
    }
    inline void change(int k,int l,int r,int x,int val){
        if(l==r){p[k].sum=val;p[k].maxx=val;return;}
        int mid=(l+r)>>1;
        if(x<=mid) change(k*2,l,mid,x,val);
        else change(k*2+1,mid+1,r,x,val);
        pushup(k);
    }
    inline int ask_sum(int k,int l,int r,int z,int y){
        if(l==z&&r==y){return p[k].sum;}
        int mid=(l+r)>>1;
        if(y<=mid) return ask_sum(k*2,l,mid,z,y);
        else if(z>mid) return ask_sum(k*2+1,mid+1,r,z,y);
        else return ask_sum(k*2,l,mid,z,mid)+ask_sum(k*2+1,mid+1,r,mid+1,y);
    }//
    inline void qumo(int k,int l,int r,int z,int y,int mod){
        if(p[k].maxx<mod){return;}
        if(l==r){p[k].sum%=mod;p[k].maxx=p[k].sum;return;}
        int mid=(l+r)>>1;
        if(y<=mid) qumo(k*2,l,mid,z,y,mod);
        else if(z>mid) qumo(k*2+1,mid+1,r,z,y,mod);
        else qumo(k*2,l,mid,z,mid,mod),qumo(k*2+1,mid+1,r,mid+1,y,mod);
        pushup(k);
    }
};
ST st;

signed main(){
    // freopen("my.in","r",stdin);
    // freopen("my.out","w",stdout); 
    read(n);read(m);
    for(int i=1;i<=n;i++) read(a[i]);
    st.build(1,1,n);
    for(int i=1;i<=m;i++){
        int op;int a,b;
        read(op);read(a);read(b);
        if(op==1) printf("%lld\n",st.ask_sum(1,1,n,a,b));
        else if(op==2){int x;read(x);st.qumo(1,1,n,a,b,x);}
        else if(op==3) st.change(1,1,n,a,b);
    }
    return 0;
}
上一篇:SAP SD基础知识之输出控制(Output Control)


下一篇:sequence 序列