1+ #include < bits/stdc++.h>
2+ using namespace std ;
3+ #define sc (x ) scanf(" %lld" , &x)
4+ typedef long long ll;
5+ #define mn 100010
6+ ll n, x[mn], t[mn], m, k, ans[mn], bin[mn], cnt[mn];
7+ ll sq, bn, bel[mn], lf[mn], rf[mn];
8+ struct query
9+ {
10+ ll l, r, i;
11+ bool operator <(const query &x) const
12+ { // 一定要这么排序
13+ return bel[l] == bel[x.l ] ? r < x.r : bel[l] < bel[x.l ];
14+ }
15+ } q[mn];
16+ void del (ll v) { --bin[v]; }
17+ void add (ll v, ll &tmp) { tmp = max (tmp, (++bin[v]) * t[v]); }
18+ signed main ()
19+ {
20+ sc (n), sc (m), sq = sqrt (n), bn = n / sq;
21+ for (ll i = 1 ; i <= n; ++i)
22+ {
23+ sc (x[i]), t[i] = x[i];
24+ }
25+ for (ll i = 1 ; i <= m; ++i)
26+ {
27+ sc (q[i].l ), sc (q[i].r ), q[i].i = i;
28+ }
29+ for (ll i = 1 ; i <= bn; ++i) // 一定要这么分块,不能/sq,不然会炸
30+ lf[i] = (i - 1 ) * sq + 1 , rf[i] = i * sq;
31+ if (rf[bn] < n)
32+ ++bn, lf[bn] = rf[bn - 1 ] + 1 , rf[bn] = n;
33+ for (ll i = 1 ; i <= bn; ++i)
34+ for (ll j = lf[i]; j <= rf[i]; ++j)
35+ bel[j] = i;
36+ sort (q + 1 , q + 1 + m);
37+ sort (t + 1 , t + 1 + n);
38+ k = unique (t + 1 , t + 1 + n) - (t + 1 );
39+ for (ll i = 1 ; i <= n; ++i)
40+ { // x[i]是输入的a[i]排在第x[i]位,离散化压[1,1e9]到[1,1e5]
41+ x[i] = lower_bound (t + 1 , t + 1 + k, x[i]) - t;
42+ }
43+ ll l = 1 , r = 0 , la = 0 , sum = 0 , l2 = 0 , sum2 = 0 ;
44+ for (ll i = 1 ; i <= m; ++i)
45+ {
46+ if (bel[q[i].l ] == bel[q[i].r ])
47+ { // 询问的左右端点同属于一个块则暴力扫描回答
48+ for (ll j = q[i].l ; j <= q[i].r ; ++j)
49+ {
50+ ++cnt[x[j]]; // 入桶
51+ }
52+ for (ll j = q[i].l ; j <= q[i].r ; ++j)
53+ { // 按题意计算
54+ ans[q[i].i ] = max (ans[q[i].i ], t[x[j]] * cnt[x[j]]);
55+ }
56+ for (ll j = q[i].l ; j <= q[i].r ; ++j)
57+ {
58+ --cnt[x[j]]; // 清理记忆
59+ }
60+ continue ;
61+ }
62+ if (bel[q[i].l ] != la) // 访问到了新的块则重新初始化莫队区间
63+ {
64+ while (r > rf[bel[q[i].l ]])
65+ del (x[r--]);
66+ while (l < rf[bel[q[i].l ]] + 1 )
67+ del (x[l++]);
68+ sum = 0 , la = bel[q[i].l ];
69+ }
70+ while (r < q[i].r ) // 扩展右端点
71+ add (x[++r], sum);
72+ l2 = l, sum2 = sum;
73+ while (l2 > q[i].l ) // 扩展左端点
74+ add (x[--l2], sum2);
75+ ans[q[i].i ] = sum2;
76+ while (l2 < l) // 回滚
77+ del (x[l2++]);
78+ }
79+ for (ll i = 1 ; i <= m; ++i)
80+ {
81+ printf (" %lld\n " , ans[i]);
82+ }
83+ return 0 ;
84+ }
0 commit comments