結果

問題 No.924 紲星
ユーザー leaf_1415leaf_1415
提出日時 2019-11-10 03:38:26
言語 C++11
(gcc 11.4.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
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 12 ms
14,464 KB
testcase_01 AC 12 ms
14,464 KB
testcase_02 AC 12 ms
14,464 KB
testcase_03 AC 18 ms
14,592 KB
testcase_04 AC 15 ms
14,464 KB
testcase_05 AC 18 ms
14,592 KB
testcase_06 AC 18 ms
14,592 KB
testcase_07 AC 15 ms
14,464 KB
testcase_08 AC 2,765 ms
32,912 KB
testcase_09 AC 2,612 ms
33,048 KB
testcase_10 AC 2,629 ms
33,048 KB
testcase_11 AC 2,725 ms
33,048 KB
testcase_12 AC 2,759 ms
33,044 KB
testcase_13 AC 1,285 ms
23,552 KB
testcase_14 AC 1,397 ms
24,448 KB
testcase_15 AC 1,187 ms
22,724 KB
testcase_16 AC 702 ms
23,736 KB
testcase_17 AC 2,133 ms
27,512 KB
testcase_18 AC 12 ms
14,464 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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