CF 121E Lucky Array 【树状数组】

这个题目的数据感觉不能更水了。从复杂度上计算,肯定有极限数据可以卡掉暴力方法的么。

总之,暴力的做法就是树状数组了,对于区间更新,就挨个更新就是了。当然,判断是否是Lucky Number的话,可以用一个数组标记一下,因为题目中有说数据不会超过10000的。总之就是一个非常不靠谱的方法过了……话说用线段树的区间操作以及延迟标记的话,真心不知道怎么判断加上d之后的Lucky Number的个数,o(╯□╰)o


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 101000
int s[N], a[N], n, m, x, y, z;
bool f[N];

void init() {
    int x;
    bool flag;
    for (int i=0; i<10004; i++) {
        flag = true;
        x = i;
        while (x) {
            if (x%10!=4 && x%10!=7) {
                flag = false; break;
            }
            x /= 10;
        }
        if (flag) f[i] = true;
        else f[i] = false;
    }
    memset(s, 0, sizeof(s));
}
inline int lowbit(int x) { return x&(-x); }
void add(int x, int v) {
    while (x <= n) {
        s[x] += v;
        x += lowbit(x);
    }
}
int sum(int x) {
    int ret = 0;
    while (x) {
        ret += s[x];
        x -= lowbit(x);
    }
    return ret;
}
int main() {
    init();
    scanf("%d%d", &n, &m);
    for (int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
        if (f[a[i]]) add(i, 1);
    }

    char op[10];
    while (m--) {
        scanf(" %s %d %d", op, &x, &y);
        if (op[0] == 'c') printf("%d\n", sum(y)-sum(x-1));
        else {
            scanf("%d", &z);
            if (z == 0) continue;
            for (int i=x; i<=y; i++) {
                if (f[a[i]]) add(i, -1);
                a[i] += z;
                if (f[a[i]]) add(i, 1);
            }
        }
    }

    return 0;
}



你可能感兴趣的:(CF 121E Lucky Array 【树状数组】)