Luogu 2048 BZOJ 2006 [NOI2010] Super Piano

【answer】

  Greedy question. Set the quintuple (mx, pos, l, r1, r2) to indicate that the maximum value is mx, the right endpoint of the interval to obtain the maximum value is pos, the left endpoint of the interval is l, and the optional interval of the right endpoint of the interval is [r1, r2] . Each time the maximum value is taken from the heap, and then the interval is split, because after the interval [l, pos] is selected, it cannot be selected again. We have to throw two new quintuples (mx',pos',l,r1,pos-1) and (mx'',pos'',l,pos+1,r2) into the heap. As for mx', To obtain mx'', pos', pos'', use the ST table.

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #define N 1000010
 6 #define rg register
 7 #define LL long long
 8 using namespace std;
 9 int n,k,L,R,tot,pos[20][N],f[20][N];
10 LL ans;
11 struct heap{
12     LL d,p,l,r1,r2;
13 }h[N];
14 struct rec{
15     LL d,p;
16 };
17 inline int read(){
18     int k=0,f=1; char c=getchar();
19     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
20     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
21     return k*f;
22 }
23 
24 inline void up(int x){
25     int fa;
26     while((fa=x>>1)&&h[fa].d<h[x].d) swap(h[fa],h[x]),x=fa;
27 }
28 inline void down(int x){
29     int son;
30     while((son=x<<1)<=tot){
31         if(son<tot&&h[son+1].d>h[son].d) son++;
32         if(h[son].d>h[x].d) swap(h[son],h[x]),x=son;
33         else return;
34     }
35 }
36 inline rec query(int l,int r){
37     r=min(r,n); l=max(1,l);
38     int k=log2(r-l+1); rec tmp; tmp.d=tmp.p=0;
39     if(l>r) return tmp;
40     if(f[k][l]>f[k][r-(1<<k)+1]){
41         tmp.d=f[k][l]; tmp.p=pos[k][l];
42         return tmp;
43     }
44     else{
45         tmp.d=f[k][r-(1<<k)+1]; tmp.p=pos[k][r-(1<<k)+1];
46         return tmp;
47     }
48 }
49 int main(){
50     memset(f,128,sizeof(f)); f[0][0]=0;
51     n=read(); k=read(); L=read()-1; R=read()-1;
52     for(rg int i=1;i<=n;i++) f[0][i]=read()+f[0][i-1],pos[0][i]=i;
53     for(rg int i=1;i<=log2(n);i++)
54         for(rg int j=1;j<=n-(1<<i)+1;j++)
55             if(f[i-1][j]>f[i-1][j+(1<<(i-1))])
56                 f[i][j]=f[i-1][j],pos[i][j]=pos[i-1][j];
57             else f[i][j]=f[i-1][j+(1<<(i-1))],pos[i][j]=pos[i-1][j+(1<<(i-1))];
58     for(rg int i=1;i<=n-L;i++){
59         rec tmp=query(i+L,i+R);
60         h[++tot]=(heap){tmp.d-f[0][i-1],tmp.p,i,i+L,min(n,i+R)};
61         up(tot);
62     }
63     for(rg int i=1;i<=k;i++){
64         heap now=h[1];
65         ans+=now.d;
66         h[1]=h[tot--]; if(tot) down(1);
67         if(now.p-1>=now.r1){
68             rec tmp=query(now.r1,now.p-1);
69             h[++tot]=(heap){tmp.d-f[0][now.l-1],tmp.p,now.l,now.r1,now.p-1};
70             up(tot);
71         }
72         if(now.r2>=now.p+1){
73             rec tmp=query(now.p+1,now.r2);
74             h[++tot]=(heap){tmp.d-f[0][now.l-1],tmp.p,now.l,now.p+1,now.r2};
75             up(tot);
76         }
77     }
78     printf("%lld\n",ans);
79     return 0;
80 }
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324715625&siteId=291194637