zoukankan      html  css  js  c++  java
  • 洛谷P3987 我永远喜欢珂朵莉~(set 树状数组)

    题意

    题目链接

    Sol

    不会卡常,自愧不如。下面的代码只有66分。我实在懒得手写平衡树了。。

    思路比较直观:拿个set维护每个数出现的位置,再写个线段树维护区间和

    #include<bits/stdc++.h>
    #define LL long long 
    const int MAXN = 5e5 + 10, INF = 1e9 + 7;
    using namespace std;
    template<typename A, typename B> inline bool chmax(A &x, B y) {
        if(y > x) {x = y; return 1;}
        else return 0;
    }
    template<typename A, typename B> inline bool chmin(A &x, B y) {
        if(y < x) {x = y; return 1;}
        else return 0;
    }
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, M, op[MAXN], ql[MAXN], qr[MAXN], val[MAXN];
    LL a[MAXN];
    bool ha[MAXN];
    set<int> s[MAXN];
    void gao(int pos,  int x) {
        for(int i = 1; i * i <= x; i++) {
            if(x % i == 0) {
                if(ha[i]) s[i].insert(pos);
                if(i != (x / i))
                    if(ha[x / i]) s[x / i].insert(pos);
            }
        }
    }
    #define lb(x) (x & (-x))
    LL T[MAXN];
    void Add(int p, int v) {
        while(p <= N) T[p] += v, p += lb(p);
    }
    LL Sum(int x) {
        LL ans = 0;
        while(x) ans += T[x], x -= lb(x);
        return ans;
    }
    LL Query(int l, int r) {
        return Sum(r) - Sum(l - 1);
    }
    void Modify(int p, int v) {
        Add(p, -a[p]);
        Add(p, a[p] / v);
    }
    
    void Change(int l, int r, int x) {
        auto it = s[x].lower_bound(l);
        while(1) {
            int pos = *it;
            if(it == s[x].end() || pos > r) return ;
            if(a[pos] % x != 0) {it++; s[x].erase(prev(it)); continue;}
            else Modify(pos, x), a[pos] /= x;
            it++;
        }
    }
    int main() {
    //	freopen("a.in", "r", stdin);
        N = read(); M = read();
        for(int i = 1; i <= N; i++) a[i] = read(), Add(i, a[i]);
        for(int i = 1; i <= M; i++) {
            op[i] = read(), ql[i] = read(); qr[i] = read();
            if(op[i] == 1) val[i] = read(), ha[val[i]] = 1;
        }
        for(int i = 1; i <= N; i++) gao(i, a[i]);
        for(int i = 1; i <= M; i++) {
            if(op[i] == 1) {
                if(val[i] != 1) Change(ql[i], qr[i], val[i]);
            } else cout << Query(ql[i], qr[i]) << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    补结对编程四则运算(结对伙伴)
    alpha发布(技术随笔)
    第四周 更新Scrum站立会议
    第四周 技术随笔psp
    第四周 课堂Scrum站立会议
    更新-补四则运算(结对编程)
    补交git、ssh
    补第二周四人小组WBS/NABCD
    补充第二周燃尽图
    修改第二周站立会议
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/10357651.html
Copyright © 2011-2022 走看看