長度為n的序列a,
定義區間內乙個數的價值為 數值*出現次數,問區間內的數的最大價值是多少。
m個詢問,每個詢問給出[l,
r][l,r]
[l,r
],問區間內數的最大價值。
1
<=n
,m<=1
05,1
<=a
i<=1
091<=n,m<=10^5,1<=a_i<=10^9
1<=n
,m<=1
05,1
<=a
i<=1
09引入乙個大佬的部落格:
這題也是乙個回滾莫隊的裸題,直接上就完事了
#include
#define rep(i, st, ed) for (int i = st; i <= ed; i++)
#define rwp(i, ed, st) for (int i = ed; i >= st; i--)
#define n 100005
using
namespace std;
typedef
long
long ll;
struct node q[n]
;int beln[n]
, sum[n]
, val[n]
, cdp[n]
, cnt[n]
, al[n]
, ar[n]
, d[n]
, n, m, siz, num;
ll ans[n]
;void
read
(int
&x)while
(s >=
'0'&& s <=
'9')
x = x * f;
}int
cmp(node aa, node bb)
void
write
(ll x)
intmain()
ar[num]
= n;
rep(i,
1, n)
read
(val[i]
), d[i]
= val[i]
;sort
(d +
1, d + n +1)
;int tot =
unique
(d +
1, d + n +1)
- d -1;
rep(i,
1, n) cdp[i]
=lower_bound
(d +
1, d + tot +
1, val[i]
)- d;
rep(i,
1, m)
read
(q[i]
.l),
read
(q[i]
.r), q[i]
.id = i;
sort
(q +
1, q + m +
1, cmp)
;int i =1;
rep(k,
0, num)
while
(r < r)
++r,
++cnt[cdp[r]
], now =
max(now,
1ll* cnt[cdp[r]
]* val[r]);
tmp = now;
while
(l > l)
--l,
++cnt[cdp[l]
], now =
max(now,
1ll* cnt[cdp[l]
]* val[l]
);
ans[q[i]
.id]
= now;
while
(l < ar[k]+1
)--cnt[cdp[l]],
++l;
now = tmp;}if
(i > m)
break;}
rep(i,
1, m)
write
(ans[i]),
printf
("\n");
return0;
}
題解 AT1219 歴史 研究
簡單分析 題面含有ioi 驚 可知此題是ioi 數字三角形 難度 逃 當然很多人都是抱著學回滾莫隊的目標來看這道題的,所以這裡介紹一下回滾莫隊。1 按莫隊的思路講詢問排序。2 查詢時列舉每個區間,我們需要保證右端點是保持單調遞增的,同時左端點每次在乙個塊中移動,以此來計算每個詢問的值。3 每一次到下...
AT1219 JOI2013 歴史 研究
回滾莫隊 題目描述 ioi國歷史研究的第一人 joi教授,最近獲得了乙份被認為是古代ioi國的住民寫下的日記。joi教授為了通過這份日記來研究古代ioi國的生活,開始著手調查日記中記載的事件。日記中記錄了連續n天發生的時間,大約每天發生一件。事件有種類之分。第i天 1 i n 發生的事件的種類用乙個...
AT1219 歴史 研究 回滾莫隊
題目描述見鏈結 直接使用莫隊,但是這道題目刪除時不好尋找次大值,考慮回滾莫隊,回滾莫隊的處理方式與莫隊大致是相同的,具體來說 對兩個相鄰的詢問區間 l r l,r l r l,r l r l r 若 b k id l bk id r bk id l bk id r bk id l b k id r ...