好不容易不 TLE 了,但是都 WA 力。。。
分块 + 分块前缀和,时间复杂度 O(qn) ,空间复杂度 O(100n+n)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
#define rop(i, a, b) for (int i = (a); i < (b); i ++ )
#define dep(i, a, b) for (int i = (a); i >= (b); i -- )
#define dop(i, a, b) for (int i = (a); i > (b); i -- )
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
const int N = 200010, M = (int)sqrt(N) + 10;
const int INF = 0x3f3f3f3f;
int len, n, m;
struct Node {
int w, s;
}p[N], s[M];
int pre[M][101];
struct Blocks {
int l = INF, r = -INF;
int cnt[101]; Node sum;
int maxn = -INF, minn = INF;
}b[M];
int get(int x) {
return (int)x / len + 1;
}
double query1(int l, int r) {
int lc = get(l), rc = get(r);
int ans = 0, len = 0;
if (lc == rc) {
for (int i = l; i <= r; i ++ )
ans += p[i].w * p[i].s, len += p[i].s;
return (double)ans / len;
}
for (int i = l; i <= b[lc].r; i ++ ) ans += p[i].w * p[i].s, len += p[i].s;
for (int i = r; i >= b[rc].l; i -- ) ans += p[i].w * p[i].s, len += p[i].s;
ans += s[rc - 1].w - s[lc].w, len += s[rc - 1].s - s[lc].s;
return (double)ans / len;
}
int query2(int l, int r) {
int cnt[101] = {0};
int lc = get(l), rc = get(r);
int answ = -INF, ans;
if (lc == rc) {
for (int i = l; i <= r; i ++ )
cnt[p[i].w] += p[i].s;
for (int i = 0; i <= 100; i ++ )
if (cnt[i] > answ) answ = cnt[i], ans = i;
return ans;
}
for (int i = l; i <= b[lc].r; i ++ ) cnt[p[i].w] += p[i].s;
for (int i = r; i >= b[rc].l; i -- ) cnt[p[i].w] += p[i].s;
for (int i = 0; i <= 100; i ++ )
cnt[i] += pre[rc - 1][i] - pre[lc][i];
for (int i = 0; i <= 100; i ++ )
if (cnt[i] > answ) answ = cnt[i], ans = i;
return ans;
}
int query3(int l, int r) {
int maxn = -INF, minn = INF;
int lc = get(l), rc = get(r);
if (lc == rc) {
for (int i = l; i <= r; i ++ )
maxn = max(maxn, p[i].w),
minn = min(minn, p[i].w);
return maxn - minn;
}
for (int i = l; i <= b[lc].r; i ++ )
maxn = max(maxn, p[i].w),
minn = min(minn, p[i].w);
for (int i = r; i >= b[rc].l; i -- )
maxn = max(maxn, p[i].w),
minn = min(minn, p[i].w);
for (int i = lc + 1; i <= rc - 1; i ++ )
maxn = max(maxn, b[i].maxn),
minn = min(minn, b[i].minn);
return maxn - minn;
}
int main() {
scanf("%d%d", &n, &m);
len = (int)sqrt(n);
for (int i = 1; i <= n; i ++ )
scanf("%d", &p[i].w);
for (int i = 1; i <= n; i ++ )
scanf("%d", &p[i].s);
for (int i = 1; i <= n; i ++ ) {
int c = get(i);
b[c].l = min(b[c].l, i);
b[c].r = max(b[c].r, i);
b[c].maxn = max(b[c].maxn, p[i].w);
b[c].minn = min(b[c].minn, p[i].w);
b[c].sum.w += p[i].w, b[c].sum.s += p[i].s;
b[c].cnt[p[i].w] += p[i].s;
}
for (int i = get(1); i <= get(n); i ++ )
s[i].w = s[i - 1].w + p[i].w,
s[i].s = s[i - 1].s + p[i].s;
for (int i = get(1); i <= get(n); i ++ )
for (int j = 0; j <= 100; j ++ )
pre[i][j] = pre[i - 1][j] + b[i].cnt[j];
while (m -- ) {
int op, l, r;
scanf("%d%d%d", &op, &l, &r);
if (op == 1) printf("%.2lf\n", query1(l, r));
if (op == 2) printf("%d\n", query2(l, r));
if (op == 3) printf("%d\n", query3(l, r));
}
return 0;
}