求助玄学问题
查看原帖
求助玄学问题
569516
C6H6楼主2023/7/19 15:06

这份代码在开了ofast的情况下寄了,应该是有ub,请大佬们帮忙看看。

#include <bits/stdc++.h>
using namespace std;
struct Query{
    int l, r, a, b, id;
}qs[100010];
int a[100010], ss[100010], bl[100010], ss2[100010];
pair<int, int> ans[100010];
int ret;
int l[256], r[256], sb[256], ln[256], rn[256], sb2[256];
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++)
const int MAXSIZE = 1 << 20;
char buf[MAXSIZE], *p1, *p2; 
void read(){}
template <class T1, class ...T2>
void read(T1& ret,T2&... rest){
    ret = 0; char c; bool f = false;
    while (!isdigit(c = gc() ) ) f = c == '-';
    while(isdigit(c) ){
        ret = (ret << 3) + (ret << 1) + (c ^ '0');
        c = gc();
    }
    if(f) ret = -ret;
    read(rest...);
}
inline bool fcmp(const Query &a, const Query &b){
    return a.l < b.l;
}
inline bool scmp(const Query &a, const Query &b){
    return a.r < b.r;
}
inline void modify(int x, int y, int z){
    ss[x] += y;
    sb[bl[x]] += y;
    ss2[x] += z;
    sb2[bl[x]] += z;
}
inline pair<int, int> ask(int x){
    int ret1 = 0, ret2 = 0;
    for(int i = 1; i < bl[x]; i++) ret1 += sb[i], ret2 += sb2[i];
    for(int i = ln[bl[x]]; i <= x; i++) ret1 += ss[i], ret2 += ss2[i];
    return {ret1, ret2};
}
inline void add(int x){
    if(__builtin_expect(ss[a[x]] == 0, 0)) modify(a[x], 1, 1);
    else modify(a[x], 1, 0);
}
inline void del(int x){
    if(__builtin_expect(ss[a[x]] == 1, 0)) modify(a[x], -1, -1);
    else modify(a[x], -1, 0);
}
inline pair<int, int> query(int a, int b){
    pair<int, int> tmp1 = ask(b), tmp2 = ask(a - 1);
    return {tmp1.first - tmp2.first, tmp1.second - tmp2.second};
}
int main(){
    int n, m;
    read(n, m);
    for(int i = 1; i <= n; i++) read(a[i]);
    for(int i = 1; i <= m; i++) read(qs[i].l, qs[i].r, qs[i].a, qs[i].b), qs[i].id = i;
    sort(qs + 1, qs + 1 + m, fcmp);
    int len = (int)(sqrt(m)) << 1;
    int T = m / len;
    if(m % T) T++;
    for(int i = 1; i < T; i++){
        l[i] = r[i - 1] + 1;
        r[i] = r[i - 1] + len;
    }
    r[T] = m;
    l[T] = r[T - 1] + 1;
    for(int i = 1; i <= T; i++) sort(qs + l[i], qs + 1 + r[i], scmp);

    int len2 = (int)(sqrt(1e5)) << 1;
    int T2 = 1e5 / len2;
    if(100000 % T2) T2++;
    for(int i = 1; i < T2; i++){
        ln[i] = rn[i - 1] + 1;
        rn[i] = rn[i - 1] + len2;
    }
    rn[T2] = 100000;
    ln[T2] = rn[T2 - 1] + 1;
    for(int i = 1; i <= T2; i++)
        for(int j = ln[i]; j <= rn[i]; j++)
            bl[j] = i;
    for(int i = 1; i <= T; i++){
        ret = 0;
        int ql = 1, qr = 2;
        add(ql); add(qr);
        for(int j = l[i]; j <= r[i]; j++){
            while(ql > qs[j].l) add(--ql);
            while(qr < qs[j].r) add(++qr);
            while(ql < qs[j].l) del(ql++);
            while(qr > qs[j].r) del(qr--);
            ans[qs[j].id] = query(qs[j].a, qs[j].b);
        }
        while(qr >= ql) del(ql++);
    }
    for(int i = 1; i <= m; i++) printf("%d %d\n", ans[i].first, ans[i].second);
 

    return 0;
}
2023/7/19 15:06
加载中...