这题也是坑了好久>_<
之前whx带我刷JOI的时候本来应该要做的。。。可是太懒没有写。。。
区间询问加权众数。
分块,预处理出块和块之间的答案,记录到第i个块数字x出现了多少次。然后查询的时候和普通众数基本一样,就是乘了个权值而已。
要离散化。
时间复杂度 O(nlogn+mn√) 。
昨晚写的常数太烂了。。。用了struct,数组开大了,狂M
然后卡了卡空间,狂RE doge
然后查了很久发现有个边界写的有点问题
改完之后就无限TLE辣QAQ
电脑课花了20min来rewrite结果就A掉了smg。。。。
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)
#define per(i,a,b) for(int i=a,_=b;i>=_;i--)
#define maxn 100007
#define maxb 331
inline int rd() {
char c = getchar();
while (!isdigit(c)) c = getchar() ; int x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x;
}
typedef long long ll;
inline void upmax(ll&a , ll b) { if (a < b) a = b ; }
typedef int arr_int[maxn];
typedef ll arr_ll [maxn];
typedef int blk_int[maxb];
typedef ll blk_ll [maxb];
int n , m , all , len , tot;
arr_int h , a , cnt , belong;
blk_ll ans[maxb];
arr_int sum[maxb] , st , ed;
void input() {
n = rd() , m = rd();
rep (i , 1 , n) h[i] = a[i] = rd();
sort(h + 1 , h + n + 1);
all = unique(h + 1 , h + n + 1) - h - 1;
rep (i , 1 , n) a[i] = lower_bound(h + 1 , h + all + 1 , a[i]) - h;
}
void init_block() {
len = (int) sqrt(n + 0.5);
rep (i , 1 , n)
belong[i] = (i - 1) / len + 1;
tot = belong[n];
rep (i , 1 , tot)
st[i] = (i - 1) * len + 1 , ed[i] = i * len;
ed[tot] = n;
rep (i , 1 , n)
sum[belong[i]][a[i]] ++;
rep (i , 1 , tot)
rep(x , 1 , all)
sum[i][x] += sum[i - 1][x];
rep (i , 1 , tot) {
rep (j , st[i] , n) cnt[a[j]] = 0;
ll mx = 0;
rep (j , st[i] , n) {
int x = a[j];
cnt[x] ++;
upmax(mx , (ll) cnt[x] * h[x]);
ans[i][belong[j]] = mx;
}
}
}
void query(int l , int r) {
ll mx = 0;
int L = belong[l] , R = belong[r];
if (L == R) {
rep (i , l , r) cnt[a[i]] ++ ;
rep (i , l , r) {
int x = a[i];
if (!cnt[x]) continue;
upmax(mx , (ll) cnt[x] * h[x]);
cnt[x] = 0;
}
} else {
if (L + 1 < R)
mx = ans[L + 1][R - 1];
rep (i , l , ed[L]) cnt[a[i]] ++ ;
rep (i , st[R] , r) cnt[a[i]] ++ ;
rep (i , l , ed[L]) {
int x = a[i];
if (!cnt[x]) continue;
ll ts = sum[R - 1][x] - sum[L][x] + cnt[x];
ts *= h[x] , cnt[x] = 0;
upmax(mx , ts);
}
rep (i , st[R] , r) {
int x = a[i];
if (!cnt[x]) continue;
ll ts = sum[R - 1][x] - sum[L][x] + cnt[x];
ts *= h[x] , cnt[x] = 0;
upmax(mx , ts);
}
}
printf("%lld\n" , mx);
}
void solve() {
init_block();
memset(cnt , 0 , sizeof cnt);
rep (i , 1 , m) {
int l = rd() , r = rd();
query(l , r);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt" , "r" , stdin);
freopen("data.out" , "w" , stdout);
#endif
input();
solve();
return 0;
}