NOI2010超级钢琴 2
2006: [NOI2010]超级钢琴
Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 1296 Solved: 606
[Submit][Status]
Description
小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。 这架超级钢琴可以弹奏出n个音符,编号为1至n。第i个音符的美妙度为Ai,其中Ai可正可负。 一个“超级和弦”由若干个编号连续的音符组成,包含的音符个数不少于L且不多于R。我们定义超级和弦的美妙度为其包含的所有音符的美妙度之和。两个超级和弦被认为是相同的,当且仅当这两个超级和弦所包含的音符集合是相同的。 小Z决定创作一首由k个超级和弦组成的乐曲,为了使得乐曲更加动听,小Z要求该乐曲由k个不同的超级和弦组成。我们定义一首乐曲的美妙度为其所包含的所有超级和弦的美妙度之和。小Z想知道他能够创作出来的乐曲美妙度最大值是多少。
Input
第一行包含四个正整数n, k, L, R。其中n为音符的个数,k为乐曲所包含的超级和弦个数,L和R分别是超级和弦所包含音符个数的下限和上限。 接下来n行,每行包含一个整数Ai,表示按编号从小到大每个音符的美妙度。
Output
只有一个整数,表示乐曲美妙度的最大值。
Sample Input
4 3 2 3
3
2
-6
8
3
2
-6
8
Sample Output
11
【样例说明】
共有5种不同的超级和弦:
音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。
【样例说明】
共有5种不同的超级和弦:
音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。
HINT
Source
题解:
唉呀,真是太感动了,竟然这么快就改好了,我还以为要一天呢,不能多说,激动啊
代码:(写得很丑)
1 const maxn=600000+10;inf=maxlongint; 2 type node=record 3 x,y,z:longint; 4 end; 5 var s,t:array[0..21,0..maxn] of longint; 6 a,b:array[0..maxn] of longint; 7 i,j,n,m,x,y,k,l,r,tmp:longint; 8 ans:int64; 9 c:array[0..2*maxn] of node; 10 w:node; 11 function max(x,y:longint):longint; 12 begin 13 if x>y then exit(x) else exit(y); 14 end; 15 16 procedure modify(x,y,z:longint); 17 var k,i:longint; 18 begin 19 c[0].x:=x;c[0].y:=y;c[0].z:=z; 20 i:=1;k:=2; 21 while k<=m do 22 begin 23 if (k<m) and (c[k+1].x>c[k].x) then inc(k); 24 if c[0].x<c[k].x then begin c[i]:=c[k];i:=k;k:=k<<1;end 25 else k:=m+1; 26 end; 27 c[i]:=c[0]; 28 end; 29 procedure insert(x,y,z:longint); 30 var k,i:longint; 31 begin 32 inc(m);c[0].x:=x;c[0].y:=y;c[0].z:=z; 33 i:=m;k:=i>>1; 34 while k>=1 do 35 begin 36 if c[0].x>c[k].x then begin c[i]:=c[k];i:=k;k:=i>>1;end 37 else k:=0; 38 end; 39 c[i]:=c[0]; 40 end; 41 procedure sort(l,r:longint); 42 var i,j,m,temp:longint; 43 begin 44 i:=l;j:=r;x:=a[(i+j)>>1]; 45 repeat 46 while b[a[i]]<b[x] do inc(i); 47 while b[a[j]]>b[x] do dec(j); 48 if i<=j then 49 begin 50 y:=a[i];a[i]:=a[j];a[j]:=y; 51 inc(i);dec(j); 52 end; 53 until i>j; 54 if i<r then sort(i,r); 55 if j>l then sort(l,j); 56 end; 57 procedure build(h,l,r:longint); 58 var i,p,mid:longint; 59 begin 60 mid:=(l+r)>>1;p:=0; 61 for i:=l to r do 62 if t[h,i]<=mid then 63 begin 64 t[h+1,l+p]:=t[h,i]; 65 inc(p); 66 s[h,i]:=p; 67 end 68 else 69 begin 70 t[h+1,mid+1+i-p-l]:=t[h,i]; 71 s[h,i]:=p; 72 end; 73 if l=r then exit; 74 build(h+1,l,mid); 75 build(h+1,mid+1,r); 76 end; 77 function find(h,l,r,x,y,k:longint):longint; 78 var ll,rr,mid:longint; 79 begin 80 if l=r then exit(t[h,l]); 81 mid:=(l+r)>>1; 82 if l=x then ll:=0 else ll:=s[h,x-1];rr:=s[h,y]-ll; 83 if rr>=k then exit(find(h+1,l,mid,l+ll,l+rr+ll-1,k)) 84 else exit(find(h+1,mid+1,r,mid+1+x-l-ll,mid+1+y-l-rr-ll,k-rr)); 85 end; 86 procedure init; 87 begin 88 readln(n,k,l,r);inc(n); 89 for i:=2 to n do begin readln(x);b[i]:=b[i-1]+x;end; 90 for i:=1 to n do a[i]:=i; 91 sort(1,n); 92 end; 93 procedure main; 94 begin 95 for i:=1 to n do t[0,a[i]]:=i; 96 build(0,1,n);//writeln(n); 97 for i:=l+1 to n do 98 begin 99 tmp:=b[a[find(0,1,n,max(i-r,1),i-l,1)]]; 100 // writeln(tmp); 101 insert(b[i]-tmp,i,1); 102 end; 103 ans:=0; 104 for i:=1 to k do 105 begin 106 w:=c[1]; // writeln(w.x); 107 inc(ans,w.x); 108 if (w.z>=r-l+1) or ((w.y<r+1) and (w.z>w.y-l-1)) then modify(-inf,inf,inf) 109 else 110 begin 111 tmp:=b[w.y]-b[a[find(0,1,n,max(w.y-r,1),w.y-l,w.z+1)]]; 112 modify(tmp,w.y,w.z+1); 113 end; 114 end; 115 writeln(ans); 116 end; 117 begin 118 assign(input,'input.txt');assign(output,'output.txt'); 119 reset(input);rewrite(output); 120 init; 121 main; 122 close(input);close(output); 123 end.