[JZOJ5439]【NOIP2017提高A组集训10.21】Fantasy

来源:互联网 发布:数据分析师招聘要求 编辑:程序博客网 时间:2024/06/07 03:27

Description

给出一个序列A
对于这个序列的每一个子串,定义其权值为这个子串的和,希望选择K 个不同的子串并使得这K 个子串的权值之和最大。(注意,不同是指左右端点其中一个不同)
由于种种限制,这些子串的长度必须在L 到R 之间。

对于100% 的数据,有1 <= N, K <= 10^5; 1 <= L < R <= N, |Ai|<= 10^4

Solution

几种做法都讲一下。

对于每一个点,它所可以选取的左端点区间内找出最优的(可以前缀和+RMQ)
都扔进堆里。

最后每次堆顶取一对元素,加入答案,然后这个最优的左端点将原本的区间分成了两部分,分别在这两部分中用RMQ找出最优的,分别与这个右端点匹配计算后加入堆,更改他们所在的区间即可。

复杂度O(NlogN+KlogN)

还有一种做法复杂度与K无关。

二分一个mid,表示所有选的子串的权值都大于等于mid

直接对于每一个右端点维护权值线段树,移动右端点时对应的区间只会删一个加一个,计算总个数。

最后刚好是K个的mid就可以用来统计答案。
复杂度O(Nlog2N)

Solution

这是第一种做法

#include <cstdio>#include <iostream>#include <algorithm>#include <cstdlib>#include <cstring>#include <cmath>#include <queue>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define N 200005#define INF 1802201963#define LL long longusing namespace std;int n,m,l,r,g[N][21],num,cf[21];LL s[N],rmq[N][21],a[N];struct node{    int l,r,y,s;    friend bool operator<(node x,node y)    {        return x.s<y.s;    }};priority_queue<node> h;int get(int x,int y){    if(x>y) return n+1;    int le=log2(y-x+1);    if(rmq[x][le]<rmq[y-cf[le]+1][le]) return g[x][le];    else return g[y-cf[le]+1][le];}void put(int l,int r,int w){    node x;    x.l=l,x.r=r,x.y=w,x.s=s[w]-s[get(x.l,x.r)];    h.push(x);}int main(){    cin>>n>>m>>l>>r;    cf[0]=1;    fo(i,1,20) cf[i]=cf[i-1]*2;    fo(i,1,n) scanf("%lld",&a[i]),s[i]=s[i-1]+a[i],rmq[i][0]=s[i],g[i][0]=i;        num=0;    fo(j,1,20)    {        fo(i,0,n)        {            if(rmq[i][j-1]<rmq[min(n,i+cf[j-1])][j-1]) rmq[i][j]=rmq[i][j-1],g[i][j]=g[i][j-1];            else rmq[i][j]=rmq[min(n,i+cf[j-1])][j-1],g[i][j]=g[min(i+cf[j-1],n)][j-1];        }    }    s[n+1]=INF;    fo(i,1,n)    {        node p;        p.l=max(0,i-r),p.r=i-l,p.y=i,p.s=s[i]-s[get(p.l,p.r)];        h.push(p);    }    LL ans=0;    fo(i,1,m)     {        node p=h.top();        ans+=p.s;        h.pop();        int w=get(p.l,p.r);        put(p.l,w-1,p.y),put(w+1,p.r,p.y);    }    printf("%lld\n",ans);}   
阅读全文
0 0