結果

問題 No.2161 Black Market
ユーザー lddlinanlddlinan
提出日時 2023-03-24 20:42:47
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 336 ms / 7,000 ms
コード長 2,776 bytes
コンパイル時間 924 ms
コンパイル使用メモリ 96,624 KB
実行使用メモリ 28,288 KB
最終ジャッジ日時 2024-09-18 16:35:48
合計ジャッジ時間 3,849 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 1 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 3 ms
5,376 KB
testcase_08 AC 3 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 2 ms
5,376 KB
testcase_11 AC 2 ms
5,376 KB
testcase_12 AC 2 ms
5,376 KB
testcase_13 AC 2 ms
5,376 KB
testcase_14 AC 2 ms
5,376 KB
testcase_15 AC 2 ms
5,376 KB
testcase_16 AC 2 ms
5,376 KB
testcase_17 AC 1 ms
5,376 KB
testcase_18 AC 2 ms
5,376 KB
testcase_19 AC 2 ms
5,376 KB
testcase_20 AC 190 ms
28,160 KB
testcase_21 AC 190 ms
27,904 KB
testcase_22 AC 76 ms
11,392 KB
testcase_23 AC 253 ms
27,904 KB
testcase_24 AC 336 ms
28,288 KB
testcase_25 AC 169 ms
22,912 KB
testcase_26 AC 326 ms
28,288 KB
testcase_27 AC 20 ms
5,376 KB
testcase_28 AC 25 ms
5,376 KB
testcase_29 AC 14 ms
5,376 KB
testcase_30 AC 9 ms
5,376 KB
testcase_31 AC 196 ms
20,096 KB
testcase_32 AC 18 ms
5,376 KB
testcase_33 AC 20 ms
5,376 KB
testcase_34 AC 5 ms
5,376 KB
testcase_35 AC 6 ms
5,376 KB
testcase_36 AC 4 ms
5,376 KB
testcase_37 AC 2 ms
5,376 KB
testcase_38 AC 8 ms
5,376 KB
testcase_39 AC 3 ms
5,376 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