【codeforces 438D】The Child and Sequence

【原题题面】传送门

【大致题意】

  • 给定一个长度为n的非负整数序列a,你需要支持以下操作:
  • 1:给定l,r,输出a[l]+a[l+1]+…+a[r]。
  • 2:给定l,r,x,将a[l],a[l+1],…,a[r]对x取模。
  • 3:给定k,y,将a[k]修改为y。

【数据范围】

  n,m<=100000,a[i],x,y<=109

【题解大意】

维护最大值和区间和,然后通过最大值有没有超过x来判断需不需要取模操作。

【code】

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define rep(k,i,j) for(int k = i;k <= j; ++k)
#define FOR(k,i,j) for(int k = i;k >= j; --k)
inline int read(){
    int x=0,f=1;   char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
    return x*f;
}
#define ls rt<<1
#define rs rt<<1|1
const int mxn = 1e5+5;
struct T {ll s;int mx;} tr[mxn<<2];
int a[mxn],n,q;
inline void build(int rt,int l,int r){
    if(l==r){
        tr[rt].s = tr[rt].mx = a[l];
        return;
    }
    int m = l+r >>1;
    build(ls,l,m),build(rs,m+1,r);
    tr[rt].s = tr[ls].s + tr[rs].s;
    tr[rt].mx = max(tr[ls].mx,tr[rs].mx);
}
inline void update(int rt,int l,int r,int lp,int rp,int x){
    if(tr[rt].mx < x) return;
    if(lp==rp){
        tr[rt].s = tr[rt].mx %= x;
        return;
    }
    int m = lp+rp >>1;
    if(l<=m) update(ls,l,r,lp,m,x);
    if(r>m) update(rs,l,r,m+1,rp,x);
    tr[rt].s = tr[ls].s + tr[rs].s;
    tr[rt].mx = max(tr[ls].mx,tr[rs].mx);
}
inline void update1(int rt,int lp,int rp,int k,int y){
    if(lp==rp){
        tr[rt].s = tr[rt].mx = y;
        return;
    }
    int m = lp+rp >>1;
    if(k<=m) update1(ls,lp,m,k,y);
    else update1(rs,m+1,rp,k,y);
    tr[rt].s = tr[ls].s + tr[rs].s;
    tr[rt].mx = max(tr[ls].mx,tr[rs].mx);
}
inline ll query(int rt,int lp,int rp,int l,int r){
    if(l<=lp&&rp<=r) {return tr[rt].s;}
    int m = lp+rp >>1;
    ll ans = 0;
    if(l<=m) ans += query(ls,lp,m,l,r);
    if(r>m) ans += query(rs,m+1,rp,l,r);
    return ans;
}
int main(){
    n = read(),q = read();
    rep(i,1,n) a[i] = read();
    build(1,1,n);
    while(q--){
        int opt = read();
        if(opt==1){
            int l = read(),r = read();
            printf("%lld\n",query(1,1,n,l,r));
        }
        if(opt==2){
            int l = read(),r = read(),x = read();
            update(1,l,r,1,n,x);
        }
        if(opt==3){
            int k = read(),y = read();
            update1(1,1,n,k,y);
        }
    }
    return 0;
}
View Code

 【调试中出过的错】

1.关于小于号和小于等于

2.关于l与lp(r与rp)的大小

posted @ 2019-03-07 20:17  ve-2021  阅读(194)  评论(0编辑  收藏  举报