线段树+主席树WA80pts求调

P2801 教主的魔法

12345xa @ 2024-01-06 19:17:30

WA #9 #10

#include<iostream>
#include<stack>
#include<cstdio>
#include<cstring>
#include<vector>
#include <algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<iomanip>
#include<iterator>

using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ri register int 
typedef long long ll;
typedef long double ld;
const int N = 1e6 + 5, M = 2e5 + 5;
const int INF = 1e9;
const ll MOD = 1e9 + 7;

int n, m;
int root[N], cnt, siz;
int a[N], b[N];
struct Node {
    int L, R, sum;
}tree[N * 10];

int tag[N << 2];
bool vis[N << 2];

int ls(int p) { return p << 1; }
int rs(int p) { return p << 1 | 1; }
void push_down(int p) {
    if (tag[p]) {
        tag[ls(p)] += tag[p];
        tag[rs(p)] += tag[p];
        vis[ls(p)] = vis[rs(p)] = 1;
        tag[p] = 0;
    }
}
void addtag(int L, int R, int p, int pl, int pr, int x) {
    vis[p] = 1;
    if (L <= pl && pr <= R) {
        tag[p] += x;
        return;
    }
    push_down(p);
    int mid = (pl + pr) >> 1;
    if (L <= mid) addtag(L, R, ls(p), pl, mid, x);
    if (R > mid) addtag(L, R, rs(p), mid + 1, pr, x);
}
int update(int pre, int pl, int pr, int x) {
    int rt = ++cnt;
    tree[rt].L = tree[pre].L;
    tree[rt].R = tree[pre].R;
    tree[rt].sum = tree[pre].sum + 1;
    int mid = (pl + pr) >> 1;
    if (pl < pr) {
        if (x <= mid) tree[rt].L = update(tree[pre].L, pl, mid, x);
        else tree[rt].R = update(tree[pre].R, mid + 1, pr, x);
    }
    return rt;
}
int ask(int u, int v, int pl, int pr, int k) {
    int x = tree[tree[v].L].sum - tree[tree[u].L].sum;
    int mid = (pl + pr) >> 1;
    int ans = 0;
    if (pl < pr) {
        if (k <= mid) ans += ask(tree[u].L, tree[v].L, pl, mid, k);
        else ans += ask(tree[u].R, tree[v].R, mid + 1, pr, k) + x;
    }
    return ans;
}
int query(int L, int R, int p, int pl, int pr, int x) {
    int ans = 0;
    if (L <= pl && pr <= R) {
        if (tag[p]) {
            int k = lower_bound(b + 1, b + 1 + siz, x - tag[p]) - b;
            ans += (tree[root[pr]].sum - tree[root[pl - 1]].sum) - ask(root[pl - 1], root[pr], 1, siz, k);
            return ans;
        }
        else if (!vis[p]) {
            int k = lower_bound(b + 1, b + 1 + siz, x) - b;
            ans += (tree[root[pr]].sum - tree[root[pl - 1]].sum) - ask(root[pl - 1], root[pr], 1, siz, k);
            return ans;
        }
    }
    push_down(p);
    int mid = (pl + pr) >> 1;
    if (L <= mid) ans += query(L, R, ls(p), pl, mid, x);
    if (R > mid) ans += query(L, R, rs(p), mid + 1, pr, x);
    return ans;
}
int main() {
    IOS;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        b[i] = a[i];
    }
    sort(b + 1, b + 1 + n);
    siz = unique(b + 1, b + 1 + n) - b - 1;
    for (int i = 1; i <= n; i++) {
        int x = lower_bound(b + 1, b + 1 + siz, a[i]) - b;
        root[i] = update(root[i - 1], 1, siz, x);
    }
    for (int i = 1; i <= m; i++) {
        char op;
        cin >> op;
        if (op == 'M') {
            int L, R, x;
            cin >> L >> R >> x;
            addtag(L, R, 1, 1, n, x);
        }
        else {
            int L, R, v;
            cin >> L >> R >> v;
            cout << query(L, R, 1, 1, n, v) << endl;
        }
    }

    return 0;
}

by ikun_god @ 2024-01-06 19:23:06

我记得要用分块吧?


by 12345xa @ 2024-01-06 19:30:30

@卷王 o(╥﹏╥)o


by LYBT @ 2024-01-06 20:02:58

主席树貌似被hack了,只能用分块


by Molie @ 2024-02-18 15:41:58

线段树不行的,,卡线段树


|