社区讨论
常规分块做法TLE,64求调
P8868[NOIP2022] 比赛参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @m09h32nm
- 此快照首次捕获于
- 2024/08/25 19:15 2 年前
- 此快照最后确认于
- 2025/11/04 22:27 4 个月前
代码:
CPP#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int MAXN = 500005;
int A[MAXN], B[MAXN], n, q, kuai;
ull AA[MAXN], BB[MAXN], CC[MAXN], lans[MAXN];
struct qua { int l, r, bh; } quary[MAXN];
struct prt { int l, r; ull Asame, Bsame, Csum, Cadd; } fk[MAXN];
inline bool cmp(qua a, qua b) { return a.r < b.r; }
inline bool cmp2(qua a, qua b) { return a.bh < b.bh; }
int gk(int x) { return (x - 1) / kuai + 1; }
inline void skA(int l, int r, int c) {
int bl = gk(l);
if (fk[bl].l == l && fk[bl].r == r) {
fk[bl].Asame = c;
} else {
if (fk[bl].Asame != 0) {
for (int i = fk[bl].l; i <= fk[bl].r; i++)
AA[i] = fk[bl].Asame;
}
fk[bl].Asame = 0;
for (int i = l; i <= r; i++) AA[i] = c;
}
}
inline void pushA(int l, int r, int c) {
if (gk(l) == gk(r)) {
skA(l, r, c);
return;
}
skA(l, fk[gk(l)].r, c);
skA(fk[gk(r)].l, r, c);
for (int i = gk(l) + 1; i < gk(r); i++)
fk[i].Asame = c;
}
inline void skB(int l, int r, int c) {
int bl = gk(l);
if (fk[bl].l == l && fk[bl].r == r) {
fk[bl].Bsame = c;
} else {
if (fk[bl].Bsame != 0) {
for (int i = fk[bl].l; i <= fk[bl].r; i++)
BB[i] = fk[bl].Bsame;
}
fk[bl].Bsame = 0;
for (int i = l; i <= r; i++) BB[i] = c;
}
}
inline void pushB(int l, int r, int c) {
if (gk(l) == gk(r)) {
skB(l, r, c);
return;
}
skB(l, fk[gk(l)].r, c);
skB(fk[gk(r)].l, r, c);
for (int i = gk(l) + 1; i < gk(r); i++)
fk[i].Bsame = c;
}
inline void skC(int l, int r) {
int i = gk(l);
if (fk[i].Asame != 0 && fk[i].Bsame != 0) {
for (int j = l; j <= r; j++)
CC[j] += fk[i].Asame * fk[i].Bsame, fk[i].Csum += fk[i].Asame * fk[i].Bsame;
} else if (fk[i].Asame == 0 && fk[i].Bsame != 0) {
for (int j = l; j <= r; j++)
CC[j] += AA[j] * fk[i].Bsame, fk[i].Csum += AA[j] * fk[i].Bsame;
} else if (fk[i].Asame != 0 && fk[i].Bsame == 0) {
for (int j = l; j <= r; j++)
CC[j] += fk[i].Asame * BB[j], fk[i].Csum += fk[i].Asame * BB[j];
} else {
for (int j = l; j <= r; j++)
CC[j] += AA[j] * BB[j], fk[i].Csum += AA[j] * BB[j];
}
}
inline void pushC(int l, int r) {
if (gk(l) == gk(r)) {
skC(l, r);
return;
}
skC(l, fk[gk(l)].r);
skC(fk[gk(r)].l, r);
for (int i = gk(l) + 1; i < gk(r); i++) {
if (fk[i].Asame != 0 && fk[i].Bsame != 0) {
fk[i].Cadd += fk[i].Asame * fk[i].Bsame;
fk[i].Csum += fk[i].Asame * fk[i].Bsame * (fk[i].r - fk[i].l + 1);
} else if (fk[i].Asame == 0 && fk[i].Bsame != 0) {
for (int j = fk[i].l; j <= fk[i].r; j++)
CC[j] += AA[j] * fk[i].Bsame, fk[i].Csum += AA[j] * fk[i].Bsame;
} else if (fk[i].Asame != 0 && fk[i].Bsame == 0) {
for (int j = fk[i].l; j <= fk[i].r; j++)
CC[j] += fk[i].Asame * BB[j], fk[i].Csum += fk[i].Asame * BB[j];
} else {
for (int j = fk[i].l; j <= fk[i].r; j++)
CC[j] += AA[j] * BB[j], fk[i].Csum += AA[j] * BB[j];
}
}
}
inline ull skask(int l, int r) {
ull ans = 0;
for (int i = l; i <= r; i++)
ans += CC[i] + fk[gk(l)].Cadd;
return ans;
}
inline ull askC(int l, int r) {
if (gk(l) == gk(r)) return skask(l, r);
ull ans = skask(l, fk[gk(l)].r) + skask(fk[gk(r)].l, r);
for (int i = gk(l) + 1; i < gk(r); i++)
ans += fk[i].Csum;
return ans;
}
signed main() {
ios::sync_with_stdio(false);
cin >> n; cin >> n; kuai = sqrt(n);
for (int i = 1; i <= n; i++) cin >> A[i];
for (int j = 1; j <= n; j++) cin >> B[j];
cin >> q;
for (int i = 1; i <= q; i++) cin >> quary[i].l >> quary[i].r;
for (int i = 1; i <= q; i++) quary[i].bh = i;
sort(quary + 1, quary + q + 1, cmp);
stack<int> s1, s2;
int gt = 1;
for (int i = 1; i <= ceil(n / (double)kuai); i++)
fk[i].l = kuai * (i - 1) + 1, fk[i].r = min(n, kuai * i);
for (int i = 1; i <= n; i++) {
while (s1.size() && A[s1.top()] < A[i]) s1.pop();
while (s2.size() && B[s2.top()] < B[i]) s2.pop();
int x1, x2;
if (s1.size()) x1 = s1.top();
else x1 = 0;
if (s2.size()) x2 = s2.top();
else x2 = 0;
s1.push(i);
s2.push(i);
pushA(x1 + 1, i, A[i]);
pushB(x2 + 1, i, B[i]);
pushC(1, i);
for (; gt <= q && quary[gt].r == i; gt++)
lans[quary[gt].bh] = askC(quary[gt].l, quary[gt].r);
}
for (int i = 1; i <= q; i++) cout << lans[i] << endl;
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...