結果
| 問題 |
No.924 紲星
|
| コンテスト | |
| ユーザー |
leaf_1415
|
| 提出日時 | 2019-11-10 03:38:26 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 2,765 ms / 4,000 ms |
| コード長 | 3,030 bytes |
| コンパイル時間 | 921 ms |
| コンパイル使用メモリ | 78,752 KB |
| 実行使用メモリ | 33,048 KB |
| 最終ジャッジ日時 | 2024-09-15 04:54:17 |
| 合計ジャッジ時間 | 23,718 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 16 |
ソースコード
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#define llint long long
#define inf 1e18
using namespace std;
typedef pair<llint, llint> P;
struct SegTree{
int size;
vector<llint> seg;
SegTree(){}
SegTree(int size){
this->size = size;
seg.resize(1<<(size+1));
}
void init()
{
for(int i = 0; i < (1<<(size+1)); i++) seg[i] = inf;
}
void update(int i, llint val)
{
i += (1 << size);
seg[i] = val;
while(i > 1){
i /= 2;
seg[i] = min(seg[i*2], seg[i*2+1]);
}
}
llint query(int a, int b, int k, int l, int r)
{
if(b < l || r < a) return inf;
if(a <= l && r <= b) return seg[k];
llint lval = query(a, b, k*2, l, (l+r)/2);
llint rval = query(a, b, k*2+1, (l+r)/2+1, r);
return min(lval, rval);
}
llint query(int a, int b)
{
return query(a, b, 1, 0, (1<<size)-1);
}
};
struct BIT{
int size;
vector<llint> bit;
BIT(){size = 0;}
BIT(int s){
size = s;
bit.resize(size+1);
init();
}
void init(){
for(int i = 1; i <= size; i++) bit[i] = 0;
}
llint query(int i){
llint ret = 0;
while(i > 0){
ret += bit[i];
i -= i&(-i);
}
return ret;
}
void add(int i, llint x){
while(i <= size){
bit[i] += x;
i += i&(-i);
}
}
};
llint n, m;
llint a[200005], s[200005];
llint l[200005], r[200005];
llint lb[200005], ub[200005];
llint ans[200005];
vector<P> vec;
priority_queue<P, vector<P>, greater<P> > Q;
SegTree seg(18), seg2(18);
BIT bit(200005), bit2(200005);
int main(void)
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= m; i++) cin >> l[i] >> r[i];
for(int i = 1; i <= n; i++) s[i] = s[i-1] + a[i];
seg.init(), seg2.init();
for(int i = 1; i <= n; i++){
vec.push_back(P(a[i], i));
seg.update(i, a[i]), seg2.update(i, -a[i]);
}
vec.push_back(P(inf, 1));
sort(vec.begin(), vec.end());
for(int i = 1; i <= m; i++){
lb[i] = seg.query(l[i], r[i]) - 1;
ub[i] = -seg2.query(l[i], r[i]);
}
while(1){
for(int i = 1; i <= m; i++){
if(ub[i]-lb[i]>1) Q.push(P((ub[i]+lb[i])/2, i));
}
if(Q.size() == 0) break;
bit.init();
for(int i = 0; i < vec.size(); i++){
while(Q.size() && Q.top().first < vec[i].first){
llint m = Q.top().first, id = Q.top().second;
if(bit.query(r[id]) - bit.query(l[id]-1) >= (r[id]-l[id]+2)/2) ub[id] = m;
else lb[id] = m;
Q.pop();
}
bit.add(vec[i].second, 1);
}
}
for(int i = 1; i <= m; i++) Q.push(P(ub[i], i));
bit.init(), bit2.init();
for(int i = 0; i < vec.size(); i++){
while(Q.size() && Q.top().first < vec[i].first){
llint m = Q.top().first, id = Q.top().second;
llint num = bit.query(r[id])-bit.query(l[id]-1), sum = bit2.query(r[id])-bit2.query(l[id]-1);
ans[id] += num * m - sum;
ans[id] += ((s[r[id]]-s[l[id]-1])-sum) - ((r[id]-l[id]+1)-num)*m;
Q.pop();
}
bit.add(vec[i].second, 1);
bit2.add(vec[i].second, a[vec[i].second]);
}
for(int i = 1; i <= m; i++) cout << ans[i] << "\n";
flush(cout);
return 0;
}
leaf_1415