QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#851331 | #9429. Subarray | Deltax | RE | 136ms | 20280kb | C++14 | 5.3kb | 2025-01-10 17:46:33 | 2025-01-10 17:46:34 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <class T>
inline void read(T &x) {
x = 0; int f = 1;
char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
while (isdigit(c)) x = (x << 1) + (x << 3) + (c & 15), c = getchar();
x = x * f;
}
const int MAXN = 1e5;
int a[MAXN + 10], b[MAXN + 10];
struct SEG {
int seg[MAXN << 2];
SEG() {}
void build(int o, int l, int r) {
if (l == r) {
seg[o] = a[l];
return;
}
int mid = l + r >> 1;
build(o << 1, l, mid), build(o << 1 | 1, mid + 1, r);
seg[o] = std::max(seg[o << 1], seg[o << 1 | 1]);
}
int findL(int o, int l, int r, int x, int y, int v) {
if (seg[o] <= v) return -1;
if (l == r) return l;
int mid = l + r >> 1, res = -1;
if (y > mid) res = findL(o << 1 | 1, mid + 1, r, x, y, v);
if (x <= mid && res == -1) res = findL(o << 1, l, mid, x, y, v);
return res;
}
int findR(int o, int l, int r, int x, int y, int v) {
if (seg[o] <= v) return -1;
if (l == r) return l;
int mid = l + r >> 1, res = -1;
if (x <= mid) res = findR(o << 1, l, mid, x, y, v);
if (y > mid && res == -1) res = findR(o << 1 | 1, mid + 1, r, x, y, v);
return res;
}
}seg;
const int Mod = 998244353;
namespace Poly {
typedef vector<int> poly;
const int MAXN = 1 << 19, G = 3;
inline int chkadd(int x) {return x >= Mod? x - Mod : x;}
inline int chksub(int x) {return x < 0? x + Mod : x;}
inline int fastpow(int x, int p) {
int ans = 1;
while (p) {
if (p & 1) ans = 1ll * ans * x % Mod;
x = 1ll * x * x % Mod;
p >>= 1;
}
return ans;
}
int inv[MAXN + 10], w1[MAXN + 10], w2[MAXN + 10], rev[MAXN + 10], revn;
inline int calc(int x) {return x != 1? 1ll << __lg(x - 1) + 1 : 0;}
void init(int n = MAXN) {
w1[0] = w2[0] = 1; rev[1] = n >> 1;
w1[1] = fastpow(G, (Mod - 1) / n); w2[n - 1] = w1[1]; revn = n; inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = 1ll * (Mod - Mod / i) * inv[Mod % i] % Mod;
//inv[i] = fastpow(i, Mod - 2);
for (int i = 2; i < n; ++i) {
w1[i] = 1ll * w1[i - 1] * w1[1] % Mod;
w2[n - i] = w1[i];
rev[i] = (rev[i >> 1] >> 1) | ((i & 1)? n >> 1 : 0);
}
}
poly NTT(poly f, int n, int op) {
int kk = __lg(revn / n);
for (int i = 0; i < n; ++i)
if (i > (rev[i] >> kk)) swap(f[i], f[rev[i] >> kk]);
int *ome = op? w2 : w1, res = revn >> 1;
for (int p = 2; p <= n; p <<= 1, res >>= 1) {
int len = p >> 1;
for (int k = 0; k < n; k += p) {
int *o = ome;
for (int l = k; l < k + len; ++l) {
int tmp = 1ll * f[l + len] * *o % Mod;
f[l + len] = chksub(f[l] - tmp);
f[l] = chkadd(f[l] + tmp);
o += res;
}
}
}
if (op) {
for (int i = 0; i < n; ++i)
f[i] = 1ll * f[i] * inv[n] % Mod;
}
return f;
}
poly MUL(poly f, int n, poly g, int m, int res) {
f.resize(n); g.resize(m); if (!res) res = n + m - 1;
int N = calc(n + m); f.resize(N); g.resize(N);
f = NTT(f, N, 0); g = NTT(g, N, 0);
for (int i = 0; i < N; ++i) f[i] = 1ll * f[i] * g[i] % Mod;
f = NTT(f, N, 1); f.resize(res);
return f;
}
}
LL ans[MAXN + 10];
vector<int> pos[MAXN + 10];
void solve(vector<int> &c) {
vector<int> f, g;
for (int i = 1; i < c.size(); ++i) f.push_back(c[i] - c[i - 1]);
g = f;
reverse(g.begin(), g.end());
//reverse(d.begin(), d.end());
int len = f.size();
vector <int> res = Poly::MUL(f, f.size(), g, g.size(), f.size() + 1);
for (int j = 1; j < len; ++j)
ans[j] = (ans[j] + res[len - 1 - j]) % Mod;
}
int main() {
Poly::init();
int T; read(T);
while (T--) {
int n; read(n);
for (int i = 1; i <= n; ++i) {
read(a[i]);
b[i] = a[i];
}
seg.build(1, 1, n);
sort(b + 1, b + n + 1);
int m = unique(b + 1, b + n + 1) - b - 1;
//for (int i = 1; i <= m; ++i) pos[i].push_back(0);
for (int i = 1; i <= n; ++i) {
int p = lower_bound(b + 1, b + m + 1, a[i]) - b;
pos[p].push_back(i);
}
for (int i = m; i >= 1; --i) {
vector<int> c;
int tmp = seg.findL(1, 1, n, 1, pos[i][0], b[i]);
if (tmp == -1) tmp = 0;
c.push_back(tmp); //d.push_back(0);
for (int j = 0; j < pos[i].size(); ++j) {
int p = seg.findR(1, 1, n, pos[i][j], n, b[i]);
if (p == -1) p = n + 1;
c.push_back(pos[i][j]);
//d.push_back(pos[i][j]);
if (j + 1 < pos[i].size() && p >= pos[i][j + 1])
continue;
c.push_back(p); //d.push_back(p);
solve(c);
c.clear(); //d.clear();
if (j + 1 < pos[i].size()) {
p = seg.findL(1, 1, n, 1, pos[i][j + 1], b[i]);
assert(p > pos[i][j]);
c.push_back(p);
//d.push_back(p);
}
}
}
LL tt = 0;
for (int i = 1; i <= n; ++i)
(tt += 1ll * i * ans[i] % Mod * ans[i]) %= Mod;
printf("%lld\n", tt);
for (int i = 1; i <= n; ++i)
ans[i] = 0;
for (int i = 1; i <= m; ++i)
pos[i].clear();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 7ms
memory: 16324kb
input:
3 11 1 1 2 1 2 2 3 3 2 3 1 3 2024 5 26 3 1000000000 1000000000 1000000000
output:
2564 36 20
result:
ok 3 lines
Test #2:
score: 0
Accepted
time: 136ms
memory: 20280kb
input:
2522 12 642802746 634074578 642802746 634074578 642802746 634074578 634074578 642802746 740396295 634074578 740396295 634074578 16 305950462 400920468 400920468 305950462 400920468 305950462 400920468 400920468 400920468 400920468 305950462 305950462 400920468 305950462 305950462 305950462 2 4405082...
output:
3610 7545 9 1 50 1006 16170 5972 3117 540 540 4417 12885 336 3185 83 9272 27 1794 2776 1793 196 27 1377 8783 19723 5385 1864 3478 7101 1 431 825 4534 9900 162 21644 6 36 14088 306 9 57 1719 72 9 4637 68 16583 17701 19390 16282 5440 1 6 1716 19541 3823 2033 24 825 429 1911 11787 11388 12255 12175 126...
result:
ok 2522 lines
Test #3:
score: -100
Runtime Error
input:
1 400000 860350786 641009859 939887597 54748096 641009859 860350786 710156469 985188306 476927808 641009859 985188306 322595515 322595515 973764525 54748096 939887597 54748096 476927808 588586447 669240390 54748096 476927808 669240390 804928248 669240390 75475634 804928248 669240390 985188306 754756...