結果
問題 | No.924 紲星 |
ユーザー | hotman78 |
提出日時 | 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 |
ソースコード
#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; } }