CF438D The Child and Sequence(线段树)

区间驱魔?看你大于模数吗,大就上,否则回家。
会不会\(T\)?每次驱魔至少变\(\frac{1}{2}\),所以\(log\),不怂
注意到叶子才更新

#include 
#include 
#include 
#include 
#include 
#include 
#define R(a,b,c) for(register int a = (b); a <= (c); ++a)
#define nR(a,b,c) for(register int a = (b); a >= (c); --a)
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define QWQ
#ifdef QWQ
#define D_e_Line printf("\n---------------\n")
#define D_e(x) cout << (#x) << " : " << x << "\n"
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#define TIME() fprintf(stderr, "\nTIME : %.3lfms\n", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
#endif
struct ios {
    template inline ios& operator >> (ATP &x) {
        x = 0; int f = 1; char c;
        for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
        while(c >= '0' && c <='9') x = x * 10 + (c ^ '0'), c = getchar();
        x *= f;
        return *this;
    }
}io;
using namespace std;
template inline ATP Max(ATP a, ATP b) {
    return a > b ? a : b;
}
template inline ATP Min(ATP a, ATP b) {
    return a < b ? a : b;
}
template inline ATP Abs(ATP a) {
    return a < 0 ? -a : a;
}

const int N = 1e5 + 7;

int n;

long long t[N << 2];
int mx[N << 2];

#define ls rt << 1
#define rs rt << 1 | 1
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
inline void Pushup(int &rt) {
    t[rt] = t[ls] + t[rs];
    mx[rt] = Max(mx[ls], mx[rs]);
}
inline void Build(int rt, int l, int r) {
    if(l == r){
        io >> t[rt];
        mx[rt] = t[rt];
        return;
    }
    int mid = (l + r) >> 1;
    Build(lson), Build(rson);
    Pushup(rt);
}
inline void Updata(int rt, int l, int r, int L, int R, int mod) {
    if(mx[rt] < mod) return;
    if(l == r){
        t[rt] %= mod;
        mx[rt] %= mod;
        return;
    }
    int mid = (l + r) >> 1;
    if(L <= mid) Updata(lson, L, R, mod);
    if(R > mid) Updata(rson, L, R, mod);
    Pushup(rt);
}
inline long long Query(int rt, int l, int r, int L, int R) {
    if(L <= l && r <= R) return t[rt];
    int mid = (l + r) >> 1;
    long long sum = 0;
    if(L <= mid) sum += Query(lson, L, R);
    if(R > mid) sum += Query(rson, L, R);
    return sum;
}
inline int QueryMax(int rt, int l, int r, int L, int R) {
    if(L <= l && r <= R) return mx[rt];
    int mid = (l + r) >> 1;
    int maxx = -1e9;
    if(L <= mid) maxx = Max(maxx, QueryMax(lson, L, R));
    if(R > mid) maxx = Max(maxx, QueryMax(rson, L, R));
    return maxx;
}
inline void Modify(int rt, int l, int r, int x, int w) {
    if(l == r){
        t[rt] = w;
        mx[rt] = w;
        return;
    }
    int mid = (l + r) >> 1;
    if(x <= mid)
        Modify(lson, x, w);
    else
        Modify(rson, x, w);
    Pushup(rt);
}

int main() {
//freopen("mod.in", "r", stdin);
//freopen("mod.out", "w", stdout);
    int m;
    io >> n >> m;
    
    Build(1, 1, n);

    while(m--){
        int opt;
        io >> opt;
        if(opt == 1){
            int l, r;
            io >> l >> r;
            printf("%lld\n", Query(1, 1, n, l, r));
        }
        else if(opt == 2){
            int l, r, mod;
            io >> l >> r >> mod;
//          if(QueryMax(1, 1, n, l, r) < mod) continue;
//          R(i,l,r){
//              Updata(1, 1, n, i, mod);
//          }
            Updata(1, 1, n, l, r, mod);
        }
        else{
            int x, w;
            io >> x >> w;
            Modify(1, 1, n, x, w);
        }
    }
    return 0;
}
/*
5 999
1 2 3 4 5 
2 3 5 4 
3 3 5 
1 2 5 
2 1 3 3 
1 1 3 
*/

CF438D The Child and Sequence(线段树)_第1张图片

你可能感兴趣的:(CF438D The Child and Sequence(线段树))