[NOI2010]超級鋼琴
阿新 • • 發佈:2017-10-01
output class har tex cst 集合 main ora 一行
[NOI2010]超級鋼琴
題目
小Z是一個小有名氣的鋼琴家,最近C博士送給了小Z一架超級鋼琴,小Z希望能夠用這架鋼琴創作出世界上最美妙的音樂。
這架超級鋼琴可以彈奏出n個音符,編號為1至n。第i個音符的美妙度為Ai,其中Ai可正可負。
一個“超級和弦”由若幹個編號連續的音符組成,包含的音符個數不少於L且不多於R。我們定義超級和弦的美妙度為其包含的所有音符的美妙度之和。兩個超級和弦被認為是相同的,當且僅當這兩個超級和弦所包含的音符集合是相同的。
小Z決定創作一首由k個超級和弦組成的樂曲,為了使得樂曲更加動聽,小Z要求該樂曲由k個不同的超級和弦組成。我們定義一首樂曲的美妙度
為其所包含的所有超級和弦的美妙度之和。小Z想知道他能夠創作出來的樂曲美妙度最大值是多少。INPUT
輸入文件名為piano.in。
輸入文件第一行包含四個正整數n, k, L, R。其中n為音符的個數,k為樂曲所包含的超級和弦個數,L和R分別是超級和弦所包含音符個數的下限和上限。
接下來n行,每行包含一個整數Ai,表示按編號從小到大每個音符的美妙度。
OUTPUT
輸出文件為piano.out。
輸出文件只有一個整數,表示樂曲美妙度的最大值。
SAMPLE
INPUT
4 3 2 3
3
2
-6
8
OUTPUT
11
解題報告
強制轉換果然不能亂用= =
枚舉左端點,用$ST$表找到滿足條件的前綴和最大區間右端點,扔進堆裏,每次取堆頂,分裂區間,再扔進堆裏
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<queue> 6 using namespace std; 7 typedef long long LL; 8 inline LL read(){ 9 LL sum(0),f(1); 10 charView Codech(getchar()); 11 for(;ch<‘0‘||ch>‘9‘;ch=getchar()) 12 if(ch==‘-‘) 13 f=-1; 14 for(;ch>=‘0‘&&ch<=‘9‘;sum=sum*10+(ch^48),ch=getchar()); 15 return sum*f; 16 } 17 LL ans; 18 struct node{ 19 int l,r; 20 LL v; 21 int L,R; 22 inline bool operator<(const node &x)const{ 23 return v<x.v; 24 } 25 }; 26 priority_queue<node>q; 27 int n,k,ll,rr; 28 LL sum[500005],mx[500005][22]; 29 int pos[500005][22]; 30 inline void ST(){ 31 for(int i=1;(1<<i)<=n;++i) 32 for(int j=1;j+(1<<i)-1<=n;++j){ 33 if(mx[j][i-1]>mx[j+(1<<i-1)][i-1]){ 34 mx[j][i]=mx[j][i-1]; 35 pos[j][i]=pos[j][i-1]; 36 } 37 else{ 38 mx[j][i]=mx[j+(1<<i-1)][i-1]; 39 pos[j][i]=pos[j+(1<<i-1)][i-1]; 40 } 41 // cout<<i<<‘ ‘<<j<<‘ ‘<<mx[j][i]<<‘ ‘<<pos[j][i]<<endl; 42 } 43 } 44 inline int query(int l,int r){ 45 if(l>r) 46 return 0; 47 int k(0),len(r-l+1); 48 while((1<<k)<=len)++k; 49 --k; 50 if(mx[l][k]>mx[r-(1<<k)+1][k]) 51 return pos[l][k]; 52 else 53 return pos[r-(1<<k)+1][k]; 54 } 55 int main(){ 56 // freopen("piano.in","r",stdin); 57 // freopen("piano.out","w",stdout); 58 n=read(),k=read(),ll=read(),rr=read(); 59 for(int i=1;i<=n;++i){ 60 sum[i]=sum[i-1]+read(); 61 mx[i][0]=sum[i]; 62 pos[i][0]=i; 63 // cout<<i<<" "<<sum[i]<<‘ ‘<<mx[i][0]<<" "<<pos[i][0]<<endl; 64 } 65 ST(); 66 for(int i=1;i<=n-ll+1;++i){ 67 int tp1(i+ll-1),tp2(min(i+rr-1,n)); 68 int tmp(query(tp1,tp2)); 69 // cout<<i<<‘ ‘<<tmp<<‘ ‘<<sum[tmp]-sum[i-1]<<‘ ‘<<tp1<<‘ ‘<<tp2<<endl; 70 q.push((node){i,tmp,sum[tmp]-sum[i-1],tp1,tp2}); 71 } 72 int cnt(0); 73 while(cnt<k){ 74 ++cnt; 75 node tmp(q.top()); 76 q.pop(); 77 ans+=tmp.v; 78 // cout<<cnt<<" "<<ans<<endl; 79 // cout<<tmp.l<<" "<<tmp.r<<" "<<tmp.v<<" "<<tmp.L<<‘ ‘<<tmp.R<<endl; 80 int tp1(query(tmp.L,tmp.r-1)),tp2(query(tmp.r+1,tmp.R)); 81 if(tmp.r-1>=tmp.L){ 82 q.push((node){tmp.l,tp1,sum[tp1]-sum[tmp.l-1],tmp.L,tmp.r-1}); 83 // cout<<"first"<<tmp.l<<‘ ‘<<tp1<<‘ ‘<<sum[tp1]-sum[tmp.l-1]<<‘ ‘<<tmp.L<<‘ ‘<<tmp.r-1<<endl; 84 } 85 if(tmp.r+1<=tmp.R){ 86 q.push((node){tmp.l,tp2,sum[tp2]-sum[tmp.l-1],tmp.r+1,tmp.R}); 87 // cout<<"second"<<tmp.l<<" "<<tp2<<‘ ‘<<sum[tp2]-sum[tmp.l-1]<<‘ ‘<<tmp.r+1<<‘ ‘<<tmp.R<<endl; 88 } 89 } 90 printf("%lld",ans); 91 }
大視野百題留念
[NOI2010]超級鋼琴