洛谷&BZOJ [POI2016]Korale

問題の[POI2016] Korale溶液

トピックリンク:P5967

件名をお願いしたいことが2つに分割されています

パート1:小さなネックレスの組み合わせのk値を見つけます

同様のアイデアタプルとスーパーピアノ、一次の値は、\((SUM、I)\)の前に記述され、iが合計の複数の選択された数(i番目の必須)の数であり、小さな反応器連続して撮影したルートを用いてスタックの最上部、および\((和+ [I + 1]、I + 1)\) と\((和+ [I + 1] - [I]、I + 1)\) ヒープを加えこのような方法はすべての状況であってもよく、トラバース単調時間の複雑さを漏れない\(\シータ(klogn)\ )

パート2:ビーズでセットを取得します

質問ANSへの回答、ランキング未満に基づいて計算またはKに等しいとANSの数はCNTました

バーストの検索は:バックを取るの数は、各試行は、それによって辞書編集最小を確保する、フロントの数を取得すると、最小のアクセス間隔は、ランクkのセットを得るために、いくつかのより少ないように、STテーブルを有するセグメントツリーを用いて可能で維持することができますので、ほとんどのk回を選択し、複雑な\(\シータ(klogn)\ )

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 1005000;

template <typename T>
void read(T &x) {
    x = 0; bool f = 0;
    char c = getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
    for (;isdigit(c);c=getchar()) x=x*10+(c^48);
    if (f) x=-x;
}

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

int n, k;

int a[N], b[N];

struct node {
    ll sum, i;
    bool operator < (const node &i) const {
        return sum > i.sum;
    }
};

priority_queue <node> q;
ll ans, cnt;

#define p1 p << 1
#define p2 p << 1 | 1
int mn[N<<2];

inline int Mn(int a, int b) {return a > b ? b : a;}
    

void build(int l, int r, int p) {
    if (l == r) return mn[p] = a[l], void();
    int mid = (l + r) >> 1;
    build(l, mid, p1), build(mid + 1, r, p2);
    mn[p] = Mn(mn[p1], mn[p2]);
}

int query(int l, int r, int p, int ql, ll x) {
    if (ql <= l) {
        if (mn[p] > x) return 0;
        if (l == r) return l;
    }
    int mid = (l + r) >> 1;
    if (ql <= mid) {
        int t = query(l, mid, p1, ql, x);
        if (t) return t;
    }
    return query(mid + 1, r, p2, ql, x);
}

int top, st[N];
void dfs(int l, ll res) {
    if (!res) {
        cnt--;
        if (!cnt) {
            cout << ans << endl;
            for (int i = 1;i <= top; i++) 
                write(st[i]), putchar(' ');
            exit(0);
        }
    }
    for (int i = l + 1;i <= n; i++) {
        i = query(1, n, 1, i, res);
        if (!i) return;
        st[++top] = i;
        dfs(i, res - a[i]);
        top--;
    }
}

int main() {
    read(n), read(k); k--;
    if (k == 0) {
        cout << 0 << endl;
        return 0;
    }
    for (int i = 1;i <= n; i++) read(a[i]), b[i] = a[i];
    sort(b + 1, b + n + 1); q.push((node){b[1], 1});
    for (int i = 1;i <= k; i++) {
        node tmp = q.top(); q.pop();
        if (tmp.sum == ans) cnt++;
        else ans = tmp.sum, cnt = 1;
        if (tmp.i == n) continue;
        tmp.i++, tmp.sum += b[tmp.i];
        q.push(tmp); tmp.sum -= b[tmp.i-1]; q.push(tmp);
    }
    build(1, n, 1); dfs(0, ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/Hs-black/p/12234065.html