CF438D The Child and Sequence

Posted czxingchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF438D The Child and Sequence相关的知识,希望对你有一定的参考价值。

外国人的数据结构题真耿直

唯一有难度的操作就是区间取模,然而这个东西可以暴力弄一下,因为一个数$x$被取模不会超过$logn$次。

证明如下(假设$x Mod   y$):

如果$y leq frac{x}{2}$那么$x$取模之后会小于$frac{x}{2}$,而如果$y > frac{x}{2}$时,$x$取模之后一定也会小于$frac{x}{2}$

然后就暴力一个一个取过去就好了,还有一个算是剪枝的优化,我们可以顺便维护一下区间最大值,如果区间最大值都小于当前的模数的话,那么就直接$return$好了。

仍然不会算时间复杂度。

丢个模板。

Code:

技术分享图片
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;

const int N = 1e5 + 5;

int n, qn;
ll a[N];

template <typename T>
inline void read(T &X) {
    X = 0;
    char ch = 0;
    T op = 1;
    for(; ch > 9|| ch < 0; ch = getchar())
        if(ch == -) op = -1;
    for(; ch >= 0 && ch <= 9; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op;
}

inline ll max(ll x, ll y) {
    return x > y ? x : y;
}

namespace SegT {
    ll s[N << 2], maxn[N << 2];
    
    #define lc p << 1
    #define rc p << 1 | 1
    #define mid ((l + r) >> 1)
    
    inline void up(int p) {
        if(p) {
            s[p] = s[lc] + s[rc];
            maxn[p] = max(maxn[lc], maxn[rc]);
        }
    }
    
    void build(int p, int l, int r) {
        if(l == r) {
            s[p] = maxn[p] = a[l];
            return;
        }
        
        build(lc, l, mid);
        build(rc, mid + 1, r);
        up(p);
    }
    
    void modify(int p, int l, int r, int x, ll v) {
        if(x == l && x == r) {
            s[p] = maxn[p] = v;
            return;
        }
        
        if(x <= mid) modify(lc, l, mid, x, v);
        else modify(rc, mid + 1, r, x, v);
        up(p);
    }
    
    void doMod(int p, int l, int r, int x, int y, ll v) {
        if(maxn[p] < v) return;
        if(l == r) {
            s[p] %= v, maxn[p] %= v;
            return;
        }
        
        if(x <= mid) doMod(lc, l, mid, x, y, v);
        if(y > mid) doMod(rc, mid + 1, r, x, y, v);
        up(p);
    } 
    
    ll query(int p, int l, int r, int x, int y) {
        if(x <= l && y >= r) return s[p];
        ll res = 0LL;
        if(x <= mid) res += query(lc, l, mid, x, y);
        if(y > mid) res += query(rc, mid + 1, r, x, y);
        return res;
    }
    
} using namespace SegT;

int main() {
    read(n), read(qn);
    for(int i = 1; i <= n; i++) read(a[i]);
    
    build(1, 1, n);
    for(int op, x, y; qn--; ) {
        read(op);
        if(op == 1) read(x), read(y), printf("%lld
", query(1, 1, n, x, y));
        if(op == 2) {
            read(x), read(y);
            ll v; read(v);
            doMod(1, 1, n, x, y, v);
        }
        if(op == 3) {
            read(x);
            ll v; read(v);
            modify(1, 1, n, x, v);
        }
    }
    
    return 0;
}
View Code

 

以上是关于CF438D The Child and Sequence的主要内容,如果未能解决你的问题,请参考以下文章

CF438D The Child and Sequence 线段树

CF438D The Child and Sequence(线段树)

CF438D The Child and Sequence

CF438D The Child and Sequence

CF438D The Child and Sequence 线段树

codeforces438D The Child and Sequence