# 【bzoj4241】历史研究

415人阅读 评论(0)

这题也是坑了好久>_<
之前whx带我刷JOI的时候本来应该要做的。。。可是太懒没有写。。。
区间询问加权众数。

#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;
}
1
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：78228次
• 积分：2187
• 等级：
• 排名：第17399名
• 原创：136篇
• 转载：0篇
• 译文：0篇
• 评论：44条
小伙伴
大神犇
阅读排行
最新评论