社区讨论

萌新刚学莫队,求助

P4396[AHOI2013] 作业参与者 2已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@locwbwpr
此快照首次捕获于
2023/10/30 20:48
2 年前
此快照最后确认于
2023/11/05 07:17
2 年前
查看原帖
RT,刚学莫队,不知道代码哪里错了,求和的地方会输出负数,下为代码
CPP
#include <bits/stdc++.h>
using namespace std;
#define R register int
const int N = 1e5 + 10;
int n, m, a[N], cnt2[N], cnt[N], sum[N];
int be[N], size, Ans1[N], Ans2[N];
struct node {
    int l, r, op, id, a, b;
}q[N];
bool inline cmp(register node x, register node y) {
    return x.op != y.op ? x.l < y.l : ((x.op & 1) ?  x.r < y.r : x.r > y.r);
}
void inline add (int x) {
    cnt[a[x]] ++; sum[(a[x] - 1) / size + 1] ++;
    if(cnt[a[x]] == 1) cnt2[a[x]] ++;
}
void inline del (int x) {
    cnt[a[x]] --; sum[(a[x] - 1) / size + 1] --;
    if(! cnt[a[x]] --) cnt2[a[x]] --;
}
int inline query (int l, int r) {
    int ans = 0;
    int opl = (l - 1) / size + 1, opr = (r - 1) / size + 1;
    if(opl == opr) {
        for(R i = l; i <= r; i ++)
            ans += cnt[i];
        return ans;
    }
    for(R i = l; i <= opl * size; i ++) ans += cnt[i];
    for(R i = opl + 1; i <= opr - 1; i ++) ans += sum[i];
    for(R i = (opr - 1) * size + 1; i <= r; i ++) ans += cnt[i];
    return ans;
}
int inline res (int l, int r) {
    int ans = 0;
    int opl = (l - 1) / size + 1, opr = (r - 1) / size + 1;
    if(opl == opr) {
        for(R i = l; i <= r; i ++)
            ans += (bool)cnt[i];
        return ans;
    }
    for(R i = l; i <= opl * size; i ++) ans += (bool)cnt[i];
    for(R i = opl + 1; i <= opr - 1; i ++) ans += cnt2[i];
    for(R i = (opr - 1) * size + 1; i <= r; i ++) ans += (bool)cnt[i];
    return ans;
}
int main ()  {
    scanf("%d%d", &n, &m); size = 670;
    for(R i = 1; i <= n; i ++)
        scanf("%d", &a[i]);
    for(R i = 1; i <= m; i ++) {
        scanf("%d%d%d%d", &q[i].l, &q[i].r, &q[i].a, &q[i].b);
        q[i].id = i; q[i].op = (q[i].l - 1) / size + 1;
    }
    sort(q + 1, q + m + 1, cmp);
    int l = 1, r = 0;
    for(R i = 1; i <= m; i ++) {
        while (l > q[i].l) add(-- l);
        while (l < q[i].l) del(l ++);
        while (r < q[i].r) add(++ r);
        while (r > q[i].r) del(r --);
        Ans1[q[i].id] = query(q[i].a, q[i].b);
        Ans2[q[i].id] = res(q[i].a, q[i].b);
    }
    for(R i = 1; i <= m; i ++)
        printf("%d %d\n", Ans1[i], Ans2[i]);
    return 0;
}

回复

5 条回复,欢迎继续交流。

正在加载回复...