# 【bzoj4241】历史研究

这题也是坑了好久>_<
之前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;
}

• 本文已收录于以下专栏：

## bzoj4241: 历史研究

• 2017年05月05日 08:52
• 441

## BZOJ4241 历史研究

• neither_nor
• 2016年04月29日 14:00
• 645

## 【bzoj4241】历史研究

• GEOTCBRL
• 2015年11月19日 15:43
• 571

## [bzoj4241]历史研究

• WerKeyTom_FTD
• 2016年03月01日 18:47
• 406

## 【bzoj4241】历史研究 分块

PoPoQQQ大神的题解： http://blog.csdn.net/popoqqq/article/details/47809173 一开始自己想了一种莫队的方法，结果发现复杂度错了...
• u012288458
• 2016年01月06日 13:59
• 889

## 【bzoj4241】 历史研究

http://www.lydsy.com/JudgeOnline/problem.php?id=4241 (题目链接)看到题目就联想到了【bzoj2809】 Apio2012—dispatching。...
• MashiroSky
• 2016年07月31日 21:22
• 173

## BZOJ4241 历史研究 莫队算法 堆

• zhouzhendongAK
• 2017年08月02日 21:28
• 175

## Bzoj4241:历史研究:莫队算法

• qq_34025203
• 2016年03月24日 17:59
• 559

## bzoj4241 历史研究 回滚莫队

• Todobe
• 2017年07月06日 15:27
• 265

## [bzoj4241]历史研究 回滚莫队

bzoj4241 历史研究 回滚莫队
• qq_37321281
• 2017年07月25日 20:21
• 97

举报原因： 您举报文章：【bzoj4241】历史研究 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)