这份代码在开了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;
}