NewTrain1 T4: [NOI2010] super piano

Topic analysis

Simply put, the title is to allow us to find a large range of pre-k size between l ~ r's.

Since each segment chord is continuous, and is included in the range of wonderful note degrees and beauty, and can be used to optimize the prefix.

There is a most simple idea is that we put all the size range between l ~ r all out of sorts. But this complexity is too great, obviously it can not pass, so consider how to optimize.

Since we are looking for pre-k large, easy to find again the whole find out, then a time to find an optimal it?

Think, do and should be correct, then in the end how to find it?

First, for each point i, j we find the greatest pair satisfying the condition of beauty and then added to a heap, so that a first ensure that the first pop-up from the top of the stack is valid interval maximum value of the entire sequence.

How to do after that? For the pop-up interval, it can be extended ah. j is i + L-1 ~ i +  R-1 between, apparent to pop this interval, we can divide it into P ~ I . 1 (L-I +. 1 <= P . 1 <j) section ~ P and I 2 (J +. 1 <= P 2 <= I-R & lt +. 1).

So we need to do, it is to find these two intervals make the biggest the p- 1 and the p- 2 position.

Seeking the interval and we will do, as long as the RMQ you can, then seek the maximum range and location, of course, it can also be made out through this process.

Of course, because we have a prefix and so can directly compare a better position in the course of which the RMQ, so RMQ direct deposit it in the corresponding period of the interval in the best position on the line.

(Refer to code) 

 1 #include<bits/stdc++.h>
 2 #define INTMAX 2147483647LL
 3 #define PII pair<int,int>
 4 #define MK make_pair
 5 #define re register
 6 using namespace std;
 7 typedef long long ll;
 8 const double Pi=acos(-1.0);
 9 const int Inf=0x3f3f3f3f;
10 const int MAXN=5e5+10; 
11 inline int read(){
12     re int x=0,f=1,ch=getchar();
13     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
14     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
15     return x*f;
16 }
17 inline ll readll(){
18     re ll x=0,f=1,ch=getchar();
19     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
20     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
21     return x*f;
22 }
23 
24 struct Node{
25     int ll,rr,idl,idr,val;
26     inline bool operator <(const Node &x)const{
27         return x.val>val;    
28     }
29 };
30 
31 ll ans;
32 int n,k,L,R;
33 int a[MAXN],sum[MAXN];
34 int RMQ[MAXN][21];
35 priority_queue<Node> q;
36 inline int Query(int l,int r){
37     int k=log2(r-l+1);
38     int x=RMQ[l][k],y=RMQ[r-(1<<k)+1][k];
39     return sum[x]>sum[y]?x:y;
40 }
41 int main(){
42     n=read();k=read();L=read();R=read();
43     for(int i=1;i<=n;++i){
44         a[i]=read();
45         sum[i]=sum[i-1]+a[i];
46         RMQ[i][0]=i;
47     }
48     for(int j=1;(1<<j)<=n;++j)
49         for(int i=1;i+(1<<j)-1<=n;++i){
50             int x=RMQ[i][j-1],y=RMQ[i+(1<<(j-1))][j-1];
51             if(sum[x]>sum[y]) RMQ[i][j]=x;
52             else RMQ[i][j]=y;
53         }
54     
55     for(int i=1;i<=n;++i)
56         if(i+L-1<=n){
57             int p=Query(i+L-1,min(i+R-1,n));
58             q.push(Node{i+L-1,min(i+R-1,n),i,p,sum[p]-sum[i-1]});
59         }
60     for(int i=1;i<=k;++i){
61         Node x=q.top();q.pop();
62         ans+=(ll)x.val;
63         if(x.ll!=x.idr){
64             int p=Query(x.ll,x.idr-1);
65             q.push((Node){x.ll,x.idr-1,x.idl,p,sum[p]-sum[x.idl-1]});
66         }
67         if(x.rr!=x.idr){
68             int p=Query(x.idr+1,x.rr);
69             q.push((Node){x.idr+1,x.rr,x.idl,p,sum[p]-sum[x.idl-1]});
70         }
71     }
72     printf("%lld\n",ans);
73     return 0;
74 }

 

Guess you like

Origin www.cnblogs.com/LI-dox/p/11261435.html