結果

問題 No.924 紲星
ユーザー hotman78hotman78
提出日時 2019-11-28 22:42:45
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 2,334 ms / 4,000 ms
コード長 3,463 bytes
コンパイル時間 3,020 ms
コンパイル使用メモリ 214,768 KB
実行使用メモリ 439,684 KB
最終ジャッジ日時 2024-11-19 06:30:22
合計ジャッジ時間 23,732 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 2 ms
6,816 KB
testcase_02 AC 2 ms
6,816 KB
testcase_03 AC 7 ms
6,816 KB
testcase_04 AC 4 ms
6,820 KB
testcase_05 AC 8 ms
6,816 KB
testcase_06 AC 7 ms
6,820 KB
testcase_07 AC 4 ms
6,816 KB
testcase_08 AC 2,273 ms
437,704 KB
testcase_09 AC 2,265 ms
439,684 KB
testcase_10 AC 2,334 ms
438,036 KB
testcase_11 AC 2,263 ms
439,224 KB
testcase_12 AC 2,279 ms
439,296 KB
testcase_13 AC 1,177 ms
199,196 KB
testcase_14 AC 1,161 ms
173,264 KB
testcase_15 AC 1,058 ms
175,280 KB
testcase_16 AC 893 ms
302,180 KB
testcase_17 AC 1,738 ms
252,204 KB
testcase_18 AC 2 ms
6,820 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace::std;
using lint=long long;
#define rep(i, n) for(lint i = 0; i < (lint)(n); i++)

__attribute__((constructor))
void init(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(15);
}

template<typename T>
class persistent_segment_tree{
	struct node;
	using np=node*;
	using lint=long long;
	struct node{
		lint val;int cnt=0;
		np ch[2]={nullptr,nullptr};
		node(){}
		node(T val):val(val){}
		node(np n):val(n->val),cnt(n->cnt){ch[0]=n->ch[0];ch[1]=n->ch[1];}
	};
	lint sz=1,n;
	int count(np t){return t?t->cnt:0;}
    vector<tuple<lint,lint,T>>p;
    vector<lint>x_list;
    vector<np>root;
    bool is_builded=0;
    T e;
    function<T(T,T)>f,g;
	public:
	persistent_segment_tree(lint n,T e,function<T(T,T)>f,function<T(T,T)>g):n(n),e(e),f(f),g(g){
		while(sz<n)sz<<=1;
	}
	void push_back(lint x,lint y,T v){
        p.emplace_back(x,y,v);
	}
    void build(){
        is_builded=1;
        sort(p.begin(),p.end());
        root.resize(p.size()+1,nullptr);
        x_list.resize(p.size());
        for(lint i=0;i<(lint)p.size();i++){
            x_list[i]=get<0>(p[i]);
            root[i+1]=push_back(get<1>(p[i]),get<2>(p[i]),root[i],-sz,sz);
        }
    }
	inline T get_fold(lint lx,lint rx,lint ly,lint ry){
		return g(get_fold(ly,ry,root[lower_bound(x_list.begin(),x_list.end(),rx)-x_list.begin()],-sz,sz),get_fold(ly,ry,root[lower_bound(x_list.begin(),x_list.end(),lx)-x_list.begin()],-sz,sz));
	}
	inline lint get_count(lint lx,lint rx,lint ly,lint ry){
		return get_count(ly,ry,root[lower_bound(x_list.begin(),x_list.end(),rx)-x_list.begin()],-sz,sz)-get_count(ly,ry,root[lower_bound(x_list.begin(),x_list.end(),lx)-x_list.begin()],-sz,sz);
	}
	inline lint kth_element(lint lx,lint rx,lint k){
		return kth_element(root[lower_bound(x_list.begin(),x_list.end(),rx)-x_list.begin()],root[lower_bound(x_list.begin(),x_list.end(),lx)-x_list.begin()],k,-sz,sz);
	}
	private:
	np push_back(lint pos,T val,np t,lint l,lint r){
		if(l<=pos&&pos<r){
			np res=t?new node(t):new node(e);
			res->val=f(res->val,val);
			res->cnt++;
			if(r-l>1){
				res->ch[0]=push_back(pos,val,res->ch[0],l,(l+r)/2);
				res->ch[1]=push_back(pos,val,res->ch[1],(l+r)/2,r);
			}
			return res;
		}else{
			return t;
		}
	}
	lint get_count(lint a,lint b,np t,lint l,lint r){
		if(!t||r<=a||b<=l)return 0;
        if(a<=l&&r<=b){return t->cnt;}
        return f(get_count(a,b,t->ch[0],l,(l+r)/2),get_count(a,b,t->ch[1],(l+r)/2,r));
	}
	T get_fold(lint a,lint b,np t,lint l,lint r){
        if(!t||r<=a||b<=l)return e;
        if(a<=l&&r<=b){return t->val;}
        return f(get_fold(a,b,t->ch[0],l,(l+r)/2),get_fold(a,b,t->ch[1],(l+r)/2,r));
    }
	lint kth_element(np s,np t,lint k,lint l,lint r){
		if(r-l==1)return l;
		if(!s)s=new node(e);
		if(!t)t=new node(e);
		lint cnt=count(s->ch[0])-count(t->ch[0]);
		if(cnt>k)return kth_element(s->ch[0],t->ch[0],k,l,(l+r)/2);
		else return kth_element(s->ch[1],t->ch[1],k-cnt,(l+r)/2,r);
	}
};
 
int main(){
	lint n,q;
	cin>>n>>q;
	vector<lint> a(n);
	rep(i,n)cin>>a[i];
	persistent_segment_tree<lint>v(1LL<<30,0,plus<lint>(),minus<lint>());
	rep(i,n)v.push_back(i,a[i],a[i]);
    v.build();
	rep(i,q){
		lint s,t;
		cin>>s>>t;
		s--;
		lint mid=v.kth_element(s,t,(t-s)/2);
		lint a=v.get_fold(s,t,mid,1LL<<30)-mid*v.get_count(s,t,mid,1LL<<30);
		lint b=-v.get_fold(s,t,-1LL<<30,mid)+mid*v.get_count(s,t,-1LL<<30,mid);
		cout<<a+b<<endl;
	}
}
0