上强度了,过了样例,但是其它的只过了 #1 #2 #3 和 #17(最后一个点),剩下的全 WA。
调很久了,感觉莫队的框架和细节都没什么问题。讨论区全部都翻了一遍,他们的 hack 都过了,他们说到的点我好像也都没什么问题(有些看不太懂不知道对没对上 qwq)。
思路是存区间内每种颜色的最左(mn)和最右(mx),每次扩展的时候,更新答案就两边都减一下比比,然后再来更新 mn 和 mx。
L 是左端点,R 是右端点,ans 是答案。用到的变量都开了 [2] 的数组,下标为 #define NOW 0 为现在使用的变量们,反过来 #define PRE 1 就是记录下来用来回滚的。
还求 dalao 们救急!调三五天了怎么调都调不出来 qwq,bdfs 也什么都查不到,要枯了(蔫
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 2e5 + 5;
int n, m, c[MAXN];
namespace DSC {
struct sblzl {
int v, idx;
} a[MAXN];
void dsc() {
// 离散化应该没问题
cin >> n;
for (int i = 1; i <= n; a[i].idx = i, i ++)
cin >> a[i].v;
sort(a + 1, a + 1 + n, [](sblzl a, sblzl b) {
return a.v < b.v;
});
for (int i = 1, lastv = 0, level = 0; i <= n; i ++) {
level += (a[i].v != lastv);
lastv = a[i].v;
a[i].v = level;
}
sort(a + 1, a + 1 + n, [](sblzl a, sblzl b) {
return a.idx < b.idx;
});
for (int i = 1; i <= n; i ++)
c[i] = a[i].v;
// cout << (c[i] = a[i].v) << ' ';
}
}
namespace LRZmustWin {
#define NOW 0
#define PRE 1
#define sqrt __builtin_sqrt
int mn[2][MAXN], mx[2][MAXN], L[2], R[2], ans[2], blen;
struct Q {
int l, r, f, idx;
} query[MAXN];
queue<int> rmQ;
void input() {
// 读入和排序, 应该没问题
cin >> m;
for (int i = 1; i <= m; query[i].idx = i, i ++)
cin >> query[i].l >> query[i].r;
blen = sqrt(n);
sort(query + 1, query + 1 + m, [](Q a, Q b) {
int aidx = (a.l - 1) / blen + 1;
int bidx = (b.l - 1) / blen + 1;
return (aidx != bidx ? aidx < bidx : a.r < b.r);
});
}
void add(int idx) {
int color = c[idx];
rmQ.push(color);
if (mn[NOW][color] == 0) {
mn[NOW][color] = idx;
mx[NOW][color] = idx;
return;
}
ans[NOW] = max(ans[NOW], max(abs(idx - mn[NOW][color]), abs(idx - mx[NOW][color])));
mn[NOW][color] = min(mn[NOW][color], idx);
mx[NOW][color] = max(mx[NOW][color], idx);
}
#define typeROLLBACK NOW
#define typeMEMORY PRE
#define typeCLS 114514
void rollmem(int rollback) {
if (rollback == typeCLS) {
while (!rmQ.empty()) {
int color = rmQ.front();
rmQ.pop();
mn[0][color] = mn[1][color] = 0;
mx[0][color] = mn[1][color] = 0;
}
L[0] = L[1] = 1;
R[0] = R[1] = 0;
ans[0] = ans[1] = 0;
return;
}
while (!rmQ.empty()) {
int color = rmQ.front();
rmQ.pop();
mn[rollback][color] = mn[!rollback][color];
mx[rollback][color] = mx[!rollback][color];
}
L[rollback] = L[!rollback];
R[rollback] = R[!rollback];
ans[rollback] = ans[!rollback];
}
void solve() {
int queryidx = 1;
for (int blockLimit = blen; queryidx <= m; blockLimit += blen) {
// 先处理同块的小问题
rollmem(typeCLS);
while (queryidx <= m && query[queryidx].r <= blockLimit) {
for (int i = query[queryidx].l; i <= query[queryidx].r; i ++)
add(i);
query[queryidx ++].f = ans[NOW];
rollmem(typeCLS);
}
// 再来正常处理所有的
L[NOW] = blockLimit + 1, R[NOW] = blockLimit;
while (queryidx <= m && query[queryidx].l <= blockLimit) {
while (R[NOW] < query[queryidx].r)
add(++ R[NOW]);
rollmem(typeMEMORY);
while (L[NOW] > query[queryidx].l)
add(-- L[NOW]);
query[queryidx ++].f = ans[NOW];
rollmem(typeROLLBACK);
}
}
}
void print() {
// 输出, 应该没问题
sort(query + 1, query + 1 + m, [](Q a, Q b) {
return a.idx < b.idx;
});
for (int i = 1; i <= m; i ++)
cout << query[i].f << '\n';
}
}
int main() {
// 这里应该就没问题了...
ios :: sync_with_stdio(0);
cin.tie(0); cout.tie(0);
DSC :: dsc();
LRZmustWin :: input();
LRZmustWin :: solve();
LRZmustWin :: print();
return 0;
}
感激不尽!(磕