結果
| 問題 |
No.2161 Black Market
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-12-12 00:25:55 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,808 bytes |
| コンパイル時間 | 2,306 ms |
| コンパイル使用メモリ | 189,128 KB |
| 実行使用メモリ | 222,044 KB |
| 最終ジャッジ日時 | 2024-10-15 19:28:34 |
| 合計ジャッジ時間 | 14,766 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 34 WA * 3 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
//2次元セグ木(自動座圧)
template <class S, S (*op)(S, S), S (*e)(), class C = long long int> struct segtree2D_lite {
int H;
std::vector<int> logsize, W;
std::vector<C> Yc;
std::vector<std::vector<C>> pos;
std::vector<std::pair<C, C>> preorder;
std::vector<std::vector<S>> d;
segtree2D_lite() {}
void insert(C y, C x){
preorder.emplace_back(y, x);
}
void build(){
for(int i = 0; i < int(preorder.size()) ; i++){
Yc.push_back(preorder[i].first);
}
std::sort(Yc.begin(), Yc.end());
Yc.erase(std::unique(Yc.begin(), Yc.end()), Yc.end());
H = 1 << ceil_pow2(Yc.size());
pos.resize(2*H), d.resize(2*H);
logsize.resize(2*H), W.resize(2*H);
for(int i = 0; i < int(preorder.size()) ; i++){
int y = std::lower_bound(Yc.begin(), Yc.end(), preorder[i].first) - Yc.begin();
y += H;
while(y){
pos[y].push_back(preorder[i].second);
y >>= 1;
}
}
for(int y = 0; y < int(pos.size()) ; y++){
std::sort(pos[y].begin(), pos[y].end());
pos[y].erase(std::unique(pos[y].begin(), pos[y].end()), pos[y].end());
logsize[y] = ceil_pow2(pos[y].size());
W[y] = 1 << logsize[y] ;
d[y].resize(2 * W[y] , e());
}
}
void set(C py, C px, S v){
int y = std::lower_bound(Yc.begin(), Yc.end(), py) - Yc.begin();
y += H;
while(y){
int x = std::lower_bound(pos[y].begin(), pos[y].end(), px) - pos[y].begin();
x += W[y];
d[y][x] = v;
x >>= 1;
while(x){
updateX(y, x);
x >>= 1;
}
y >>= 1;
}
}
S get(C py, C px){
int y = std::lower_bound(Yc.begin(), Yc.end(), py) - Yc.begin();
y += H;
int x = std::lower_bound(pos[y].begin(), pos[y].end(), px) - pos[y].begin();
return d[y][x + W[y]];
}
S prod(C lpy, C lpx , C rpy , C rpx){
int ly = std::lower_bound(Yc.begin(), Yc.end(), lpy) - Yc.begin();
int ry = std::lower_bound(Yc.begin(), Yc.end(), rpy) - Yc.begin();
S sml = e(), smr = e();
ly += H, ry += H ;
while (ly < ry) {
if (ly & 1) sml = op(sml, yline_prod(lpx, rpx , ly++));
if (ry & 1) smr = op(yline_prod(lpx, rpx , --ry), smr);
ly >>= 1, ry >>= 1;
}
return op(sml, smr);
}
S yline_prod(C lpx, C rpx , int y){
int lx = std::lower_bound(pos[y].begin(), pos[y].end(), lpx) - pos[y].begin();
int rx = std::lower_bound(pos[y].begin(), pos[y].end(), rpx) - pos[y].begin();
S sml = e(), smr = e();
lx += W[y], rx += W[y] ;
while (lx < rx) {
if (lx & 1) sml = op(sml, d[y][lx++]);
if (rx & 1) smr = op(d[y][--rx], smr);
lx >>= 1, rx >>= 1;
}
return op(sml, smr);
}
private:
int ceil_pow2(int n) {
int x = 0;
while ((1U << x) < (unsigned int)(n)) x++;
return x;
}
void updateX(int yi, int xi) { d[yi][xi] = op(d[yi][2 * xi], d[yi][2 * xi + 1]); }
};
ll op(ll lhs, ll rhs){
return lhs + rhs;
}
ll e(){return 0;}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
ll N, K, L, P;
cin >> N >> K >> L >> P;
int n1 = N / 2, n2 = N - n1;
vector<ll> a(N), b(N);
for(int i = 0; i < N; i++)cin >> a[i] >> b[i];
vector<vector<pair<ll,ll>>> c(n1 + 1), d(n2 + 1);
segtree2D_lite<ll, op, e> seg;
for(int i = 0; i < (1 << n1); i++){
ll s1 = 0, s2 = 0;
for(int j = 0; j < n1; j++){
if(i >> j & 1){
s1 += a[j];
s2 += b[j];
}
}
c[__builtin_popcount(i)].emplace_back(s1, s2);
seg.insert(L + 1 - s1, P - s2);
}
for(int i = 0; i < (1 << n2); i++){
ll s1 = 0, s2 = 0;
for(int j = 0; j < n2; j++){
if(i >> j & 1){
s1 += a[j + n1];
s2 += b[j + n1];
}
}
d[__builtin_popcount(i)].emplace_back(s1, s2);
seg.insert(s1, s2);
}
seg.build();
ll ans = 0;
for(int ci = min(n1, int(K)), di = 0; ci >= 0; ci--){
while(di <= n2 && ci + di <= K){
for(auto &&p:d[di]){
seg.set(p.first, p.second, seg.get(p.first, p.second) + 1);
}
di++;
}
for(auto &&p:c[ci]){
ll ly = 0, ry = L + 1 - p.first;
if(ry <= ly)continue;
ans += seg.prod(ly, P - p.second, ry, 1ll << 62);
}
}
cout << ans << '\n';
}