スーパーピアノ

問題の意味

所与の配列は、セット内の連続体の弦長さ[L、R]、それらの要素および値として定義されます。最も上位k個のコードと値を探しています。


考え

、列挙左ポイント列挙して、最大のポイントを取得する権利を回す:暴力のアイデアは明らかです。

最適化の考慮事項:左エンドポイントのそれぞれについて、最大値を求めることができる\ [マックス{和[J] } -和[chosen_point] \]

最大値テーブルの最適化プロセスを選択すると、STを使用することができ、その後、杭を配置します。

コード

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

    template<typename T>inline void read (T &x) {
        x=0;T f=1;char c=getchar();
        for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
        for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
        x*=f;
    }

    template<typename T>inline void write (T x) {
        if (x<0) putchar('-'),x*=-1;
        if (x>=10) write(x/10);
        putchar(x%10+'0');
    }

}

using namespace StandardIO;

namespace Project {
    #define int long long
    
    const int N=500500;
    
    int n,k,L,R,ans;
    int st[N][20];
    int sum[N];
    struct node {
        int val,lpos,rpos,r;
        node () {}
        node (int _v,int _l,int _r,int _rr) : val(_v),lpos(_l),rpos(_r),r(_rr) {}
        friend inline bool operator < (const node x,const node y) {
            return x.val<y.val;
        }
    };
    priority_queue<node> q;
    
    inline int min (int a,int b) {
        return (sum[a]<sum[b])?a:b;
    }
    inline int query (int l,int r) {
        if (l>r) return -1;
        int x=log2(r-l+1);
        return min(st[l][x],st[r-(1<<x)+1][x]);
    }

    inline void MAIN () {
        read(n),read(k),read(L),read(R);
        for (register int i=1; i<=n; ++i) {
            read(sum[i]),sum[i]+=sum[i-1],st[i][0]=i;
        }
        for (register int i=1; (1<<i)<=n; ++i) {
            for (register int j=0; (1<<i)+j-1<=n; ++j) {
                st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
            }
        }
        for (register int i=L; i<=n; ++i) {
            int tmp=query(max(0ll,i-R),i-L);
            q.push(node(sum[i]-sum[tmp],max(i-R,0ll),i-L,i));
        }
        for (register int i=1; i<=k; ++i) {
            node now=q.top();q.pop(),ans+=now.val;
            int tmp=query(now.lpos,now.rpos),s=query(now.lpos,tmp-1),t=query(tmp+1,now.rpos);
            if (s!=-1) q.push(node(sum[now.r]-sum[s],now.lpos,tmp-1,now.r));
            if (t!=-1) q.push(node(sum[now.r]-sum[t],tmp+1,now.rpos,now.r));
        }
        write(ans);
    }
    
    #undef int
}

int main () {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    Project::MAIN();
}

おすすめ

転載: www.cnblogs.com/ilverene/p/11521483.html