結果

問題 No.2161 Black Market
ユーザー lddlinanlddlinan
提出日時 2023-03-24 20:42:47
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
AC  
実行時間 362 ms / 7,000 ms
コード長 2,776 bytes
コンパイル時間 950 ms
コンパイル使用メモリ 96,644 KB
実行使用メモリ 30,140 KB
最終ジャッジ日時 2023-10-18 20:35:36
合計ジャッジ時間 4,120 ms
ジャッジサーバーID
(参考情報)
judge15 / judge11
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,312 KB
testcase_01 AC 2 ms
5,312 KB
testcase_02 AC 3 ms
5,356 KB
testcase_03 AC 2 ms
4,348 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 3 ms
5,404 KB
testcase_07 AC 3 ms
5,404 KB
testcase_08 AC 3 ms
5,404 KB
testcase_09 AC 2 ms
5,364 KB
testcase_10 AC 3 ms
5,404 KB
testcase_11 AC 2 ms
5,392 KB
testcase_12 AC 2 ms
5,348 KB
testcase_13 AC 2 ms
5,320 KB
testcase_14 AC 2 ms
5,324 KB
testcase_15 AC 2 ms
5,372 KB
testcase_16 AC 2 ms
5,316 KB
testcase_17 AC 2 ms
4,348 KB
testcase_18 AC 2 ms
4,348 KB
testcase_19 AC 2 ms
4,348 KB
testcase_20 AC 225 ms
29,884 KB
testcase_21 AC 229 ms
29,884 KB
testcase_22 AC 83 ms
13,284 KB
testcase_23 AC 285 ms
29,884 KB
testcase_24 AC 362 ms
30,140 KB
testcase_25 AC 183 ms
24,844 KB
testcase_26 AC 345 ms
30,140 KB
testcase_27 AC 20 ms
5,772 KB
testcase_28 AC 24 ms
6,716 KB
testcase_29 AC 14 ms
6,896 KB
testcase_30 AC 11 ms
6,348 KB
testcase_31 AC 205 ms
21,948 KB
testcase_32 AC 19 ms
5,328 KB
testcase_33 AC 21 ms
7,388 KB
testcase_34 AC 5 ms
4,348 KB
testcase_35 AC 6 ms
4,348 KB
testcase_36 AC 3 ms
4,348 KB
testcase_37 AC 3 ms
5,332 KB
testcase_38 AC 8 ms
4,348 KB
testcase_39 AC 3 ms
5,316 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <algorithm>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <string>
using namespace std;

bool rcmp(int a, int b) { return a>b; }
typedef long long LL;
class mypcmp {
public:
    bool operator()(const int& a, const int& b) {
        return a<b;
    }
};


multiset<pair<LL, LL>> ss1[18];
multiset<pair<LL, LL>> ss2[18];
LL vv[1<<17];
int mx, ix[1<<19];
int as[64], bs[64];
void setv(int i, int v) {
    i+=mx;
    while(i) { ix[i]+=v; i>>=1; }
}
int count(int s, int e) {
    int r=0;
    s+=mx; e+=mx;
    while(s<=e) {
        if (s&1) { r+=ix[s]; s++; }
        if ((e&1)==0) { r+=ix[e]; e--; }
        s>>=1; e>>=1;
    }
    return r;
}
int main() {
    int n, i, k, l, p, m, x, mm, m2, c, j, jj, ii;
    LL a, b, r=0, xv;
    multiset<pair<LL, LL>> ss;
    scanf("%d %d %d %d", &n, &k, &l, &p);
    for (i=0; i<n; i++) scanf("%d %d", &as[i], &bs[i]);
    m = (n+1)/2;
    mm = 1<<m;
    for (x=1; x<mm; x++) {
        c=0; a=b=0;
        for (i=0; i<m; i++) if ((1<<i)&x) {
            c++;
            a+=as[i]; b+=bs[i]; 
        }
        if (a>l||c>k) continue;
        ss1[c].insert({a, b});
        if (b>=p) r++;
    }
    m2=n-m;
    mm = 1<<(n-m);
    for (x=1; x<mm; x++) {
        c=0; a=b=0;
        for (i=0; i<m2; i++) if ((1<<i)&x) {
            c++;
            a+=as[i+m]; b+=bs[i+m]; 
        }
        if (a>l||c>k) continue;
        ss2[c].insert({a, b});
        if (b>=p) r++;
    }
    i=k; if (i>m) i=m; j=0;
    for (i=m; i>0; i--) {
        if (ss1[i].size()==0) continue;
        while(j+i<=k&&j<=m2) {
            for (auto x: ss2[j]) ss.insert(x);
            j++;
        }
        if (ss.size()==0) continue;
        // build seg
        c=0; for (auto x: ss1[i]) {
            vv[c++]=x.second;
        } sort(vv, vv+c);
        jj=0; for (ii=0; ii<c; ii++) {
            if (ii&&vv[ii]==vv[ii-1]) continue;
            vv[jj++]=vv[ii];
        } c=jj;
        // printf("%d:%d:", i, c); for (j=0; j<c; j++) printf(" %lld", vv[j]); printf("\n");
        mx=1; while(mx<=c) mx<<=1; memset(ix, 0, sizeof(ix[0])*(mx+mx));
        for (auto x: ss1[i]) {
            setv(lower_bound(vv, vv+c, x.second)-vv, 1);
        }
        auto e = ss1[i].rbegin();
        for (auto x: ss) {
            while(e!=ss1[i].rend()) {
                if (e->first+x.first<=l) break;
                setv(lower_bound(vv, vv+c, e->second)-vv, -1);
                e++;
            }
            if (e==ss1[i].rend()) break;
            xv = p-x.second;
            r+=count(lower_bound(vv, vv+c, xv)-vv, c);
        }
    }
    printf("%lld\n", r);

    return 0;
}
0