Problem:
Problem G : Everything Starts With Your Vote
ヒューリスティクスという言葉がある。確実にうまくいくという保証はないけれども大抵の場合はうまくいく、比較的単純なアプローチのことだ。単純にして強力であるがゆえに、この世の中は多くのヒューリスティクスで満ち溢れている。
ヒューリスティクスの一例として、こんなものが挙げられる。アニメ番組において、あるキャラクターの人気度は、そのアニメ本編中における登場時間の総和に比例する。確かにこれは多くの場合に成り立っているようだ。しかし、どうやら僕は少数派に属するらしい。影の薄いキャラ、背景にちらりと映るモブキャラなんかに限って可愛く見えたりするのだ。
自分の好きなキャラのことを、他人がどう思っていようがいいじゃないか。とは言ってられない事情が、残念ながらある。関連商品、フィギュアやキャラクターソングCDなどは、人気のあるキャラのものから優先的に発売される傾向にあるのだ。商業的には当然の選択だとはいえ、不人気キャラのファンの肩身は狭い。
そこで重要となってくるのが、アニメ番組の制作会社によって行われる人気投票である。実際の人気がどうであれ、ここで多くの票を獲得すれば、関連商品への道が開かれるのだ。どんな手段を使っても票を集めねばなるまい。
厳正なる投票のために、ある関連商品を1つ購入するたびに1票の投票権が与えられる。この仕組を厳正と呼ぶべきかどうかは今大きく議論されているが、とにかく僕は
L
票の投票権を得た。投票の対象となるキャラは全部で
N
人いて、より多くの票を獲得した
K
人のキャラ (同票の場合は名前の辞書順) の関連商品が企画されることになる。僕の好きなキャラは全部で
M
人いて、その中からできるだけ多くのキャラを上位
K
人に入れたいと思っている。
僕はまず、それぞれのキャラがどれだけの票を獲得するかを予測した(難しいことではない。あるキャラクターの人気度は、その登場時間の総和に比例すると仮定しただけだ)。この予測が正しいとして、より多くの僕の好きなキャラの関連商品が発売されるようにするためには、僕はこの
L
票を誰にどれだけ投じればいいだろうか。
Input
入力は複数のケースからなる。
各ケースは以下のフォーマットで与えられる。
N
M
K
L
name
0
x
0
.
.
.
name
N-1
x
N-1
fav
0
.
.
.
fav
M-1
N
、
M
、
K
、
L
の意味は問題文に記されているとおりである。
name
i
はキャラクターの名前、
x
i
は
i
番目のキャラクターの票の総数を表す。
fav
i
はあなたがひいきしているキャラクターの名前を表す。これらの名前は必ず異なり、また必ずキャラクターの名前の入力の中に含まれる。
入力の終わりは
N
= 0 かつ
M
= 0 かつ
K
= 0 かつ
L
= 0からなる行によって与えられる
また各値は以下の条件を満たす
1 ≤
N
≤ 100,000
1 ≤
M
≤
N
1 ≤
K
≤
N
1 ≤
L
≤ 100,000,000
0 ≤
x
i
≤ 100,000,000
name
i
はアルファベットのみを含み、長さは10文字以下である。
テストケースの数は150を超えない。
また20,000 ≤
N
となるケースの数は20を超えないことが保証されている。
ジャッジデータは大きいので、速い入力を使うことを推奨する。
Output
M
人のキャラの中から最大で何人を上位
K
人に入れることが出来るかを1行で出力せよ。
Sample input
4 1 3 4
yskwcnt 16
akzakr 7
tsnukk 12
fnmyi 13
akzakr
4 1 3 5
akzakr 7
tsnukk 12
fnmyi 13
yskwcnt 16
akzakr
4 2 2 1
akzakr 4
tsnukk 6
yskwcnt 6
fnmyi 12
akzakr
fnmyi
5 2 3 28
knmmdk 6
skrkyk 14
tmemm 14
akmhmr 15
mksyk 25
knmmdk
skrkyk
5 2 3 11
tmemm 12
skrkyk 18
knmmdk 21
mksyk 23
akmhmr 42
skrkyk
tmemm
14 5 10 38
iormns 19
hbkgnh 23
yyitktk 31
rtkakzk 36
mmftm 43
ykhhgwr 65
hrkamm 66
ktrotns 67
mktkkc 68
mkhsi 69
azsmur 73
tknsj 73
amftm 81
chyksrg 88
mkhsi
hbkgnh
mktkkc
yyitktk
tknsj
14 5 10 38
mktkkc 24
rtkakzk 25
ykhhgwr 25
hrkamm 27
amftm 37
iormns 38
tknsj 38
yyitktk 39
hbkgnh 53
mmftm 53
chyksrg 63
ktrotns 63
azsmur 65
mkhsi 76
mkhsi
hbkgnh
mktkkc
yyitktk
tknsj
0 0 0 0
Sample output
0
1
1
2
1
4
5
The University of Aizu Programming Contest 2011 Summer
原案: Tomoya Sakai
問題文: Takashi Tayama

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int, int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const ll ll_MAX = 0x7fffffffffffffff;
const int int_INF = 0x3f3f3f3f;
const int int_MAX = 0x7fffffff;
const double EPS = 1e-7;
const double PI = acos(-1.0);
const int dy[8] = {-1, 0, 1, 0, 1, -1, 1, -1};
const int dx[8] = {0, -1, 0, 1, 1, -1, -1, 1};
#define R register
#define _max(a, b) ((a) > (b) ? (a) : (b))
#define _min(a, b) ((a) < (b) ? (a) : (b))
#define _abs(a) ((a) > 0 ? (a) : -(a))
#define _swap(a, b) ((a) ^= (b) ^= (a) ^= (b))
#define _eql(x, y) (_abs((x) - (y)) < EPS)
const int MOD = 1e9 + 7;
const int MX = 1000010;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while(c > '9' || c < '0') {
        if(c == '-')
            f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
        x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f == -1 ? -x : x;
}
map<string, int> mp;
struct Node {
    string name;
    int tick;
    int want;
} person[100010];
struct Idol {
    int ID;
    int tick;
} my[100010], enemy[100010];
int cnt1 = 0, cnt2 = 0;
int n, m, k, l;
bool cmp(Node a, Node b) {
    if(a.tick == b.tick)
        return a.name < b.name;
    return a.tick > b.tick;
}
bool Init() {
    mp.clear();
    cnt1 = cnt2 = 0;

    cin >> n >> m >> k >> l;
    if(n == 0 && m == 0 && k == 0 && l == 0)
        return 0;
    for(int i = 0; i < n; i++) {
        cin >> person[i].name >> person[i].tick;
        mp[person[i].name] = i;
        person[i].want = 0;
    }

    string name;
    for(int i = 0; i < m; i++) {
        cin >> name;
        person[mp[name]].want = 1;
    }
    return 1;
}
bool check(int x) {  //进入人数
    ll need = 0;
    for(int i = 0; i < x; i++) {
        if(my[i].tick > enemy[k - x].tick)
            continue;
        else {
            need += enemy[k - x].tick - my[i].tick;
            if(enemy[k - x].ID < my[i].ID)
                need++;
        }
    }
    return need <= l;
}
void solve() {
    sort(person, person + n, cmp);

    for(int i = 0; i < n; i++) {
        if(person[i].want) {
            my[cnt1].tick = person[i].tick;
            my[cnt1].ID = mp[person[i].name];
            cnt1++;
        }
        else {
            enemy[cnt2].tick = person[i].tick;
            enemy[cnt2].ID = mp[person[i].name];
            cnt2++;
        }
    }

    int mn = min(m - n + k, 0);
    int mx = min(k, m);
    int l = 1, r = n;
    while(l < r) {
        int mid = (l + r) >> 1;
        if(mid > mx)
            r = mid;
        else if(mid < mn)
            l = mid + 1;
        else if(check(mid)) {
            l = mid + 1;
        }
        else {
            r = mid;
        }
    }
    printf("%lld\n", l - 1);
}
int main() {
    std::ios::sync_with_stdio(false);
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    int t = 1;
    // cin>> t;
    while(Init()) {
        solve();
    }
    return 0;
}
accuracy: 0.25
time_ms: 1200
memory_kb: 17252
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using db = double;
using ld = long double;
#define fs first
#define sc second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define all(v) (v).begin(), (v).end()
#define siz(v) (ll)(v).size()
#define rep(i, a, n) for (ll i = a; i < (ll)(n); i++)
#define repr(i, a, n) for (ll i = n - 1; (ll)a <= i; i--)
#define lb lower_bound
#define ub upper_bound
typedef pair<int, int> P;
typedef pair<ll, ll> PL;
const ll mod = 1000000007;
const ll INF = 1000000099;
const ll LINF = (ll)(1e18 + 99);
vector<ll> dx = {-1, 1, 0, 0}, dy = {0, 0, -1, 1};
template <typename T>
T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template <typename T>
T mpow(T a, T n)
{
   T res = 1;
   for (; n; n >>= 1)
   {
      if (n & 1)
         res = res * a;
      a = a * a;
   }
   return res;
}

//cin.tie(0);ios::sync_with_stdio(false);

signed main()
{
   cin.tie(0);
   ios::sync_with_stdio(false);

   while (1)
   {
      ll n, m, k, l;
      cin >> n >> m >> k >> l;
      if (!n && !m && !k && !l)
         return 0;

      vector<pair<ll, string>> v(n);
      vector<pair<ll, string>> flist(0);

      rep(i, 0, n) cin >> v[i].sc >> v[i].fs;

      sort(all(v));
      reverse(all(v));


      set<string> fav;
      rep(i, 0, m)
      {
         string in;
         cin >> in;
         fav.insert(in);
      }

      for (int i = n - 1; 0 <= i; i--)
      {
         if (fav.count(v[i].sc))
         {
            flist.pb(v[i]);
            if (i + 1 < n)
               v[i] = v[i + 1];
            else
               v[i].fs = -1;
         }
      }
      sort(all(flist));
      reverse(all(flist));


      ll ok = 0, ng = min(m, k) + 1; //
      while (abs(ok - ng) > 1)
      {
         ll mid = (ok + ng) / 2;

         ll cost = 0;
         rep(i, 0, mid)
         {
            if (v[k - mid].fs - flist[i].fs > 0)
            {
               cost += v[k - mid].fs - flist[i].fs;

               if (v[k - mid].sc < flist[i].sc)
                  cost++;
            }
         }

         if (cost <= l)
            ok = mid;
         else
            ng = mid;
      }

      cout << ok << endl;
   }
}
accuracy: 0.25
time_ms: 650
memory_kb: 21384
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct data {
  string name;
  long long x;
};
bool operator<(const data &l, const data &r) {
  if(l.x != r.x) return l.x > r.x;
  return l.name < r.name;
}

long long n, m, k, l;
vector<data> v;
set<string> fav;
vector<long long> lst;

long long solve();
bool ch(long long top);

int main() {
  while(1) {
    cin >> n >> m >> k >> l;
    if(n + m + k + l == 0) break;
    v.resize(n);
    lst.clear();
    fav.clear();
    for(int i = 0; i < n; ++i) cin >> v[i].name >> v[i].x;
    for(int i = 0; i < m; ++i) {
      string s;
      cin >> s;
      fav.insert(s);
    }
    cout << solve() << endl;
  }
  return 0;
}

long long solve() {
  sort(v.begin(), v.end());
  for(int i = 0; i < n; ++i)
    if(fav.find(v[i].name) != fav.end()) lst.push_back(i);
  long long l = 0, r = min(k, m) + 1;
  while(r - l > 1) {
    long long now = (l + r) / 2;
    if(ch(now))
      l = now;
    else
      r = now;
  }
  return l;
}

bool ch(long long top) {
  long long remain = l, under = top;
  for(int i = 0; i < top; ++i) {
    long long nowid = lst[i];
    if(nowid <= k - under) {
      --under;
      continue;
    }
    remain -= v[k - under].x - v[nowid].x +
              (v[nowid].name > v[k - under].name);
  }
  return remain >= 0;
}
accuracy: 1
time_ms: 950
memory_kb: 18500
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, string> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

ll N,M,K,L;
bool isfav[100010];
vector<ll> A,fav;
vector<string> S;
map<string,ll> id;
vector<ll> ord;

bool ok(ll X){
  if(X>K)return false;

  ll cnt=0;
  rep(i,K){
    if(isfav[ord[i]])cnt++;
  }
  if(X<=cnt)return true;

  ll add=X;
  ll rest=X-cnt;
  ll sum=0;
  for(ll i=K-1;i>=0;i--){
    if(!isfav[ord[i]]){
      rest--;
      if(rest==0){
        rep(j,N){
          if(isfav[ord[j]]){
            if(j>i){
              if(S[ord[i]]<S[ord[j]]) sum+=A[ord[i]]-A[ord[j]]+1;
              else sum+=A[ord[i]]-A[ord[j]];
            }
            add--;
            if(add==0)break;
          }
        }
        break;
      }
    }
  }
  return sum<=L;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  while(1){
    A.clear(); S.clear(); fav.clear(); ord.clear();
    id.clear();
    cin>>N>>M>>K>>L;
    if(N==0)break;
    rep(i,N)isfav[i]=false;
    A.resize(N);
    S.resize(N);
    rep(i,N){
      string name;
      cin>>S[i]>>A[i];
      id[S[i]]=i;
    }
    rep(i,M){
      string name;
      cin>>name;
      fav.push_back(id[name]);
      isfav[id[name]]=true;
    }

    rep(i,N){
      ord.push_back(i);
    }
    sort(all(ord),[=](const ll& a,const ll& b){
      if(A[a]==A[b])return S[a]<S[b];
      else return A[a]>A[b];
    });

    //rep(i,N){
      //dbg(S[ord[i]]);
    //}

    ll lb=0,ub=M+1;
    while(ub-lb>1){
      ll mid=(ub+lb)/2;
      if(ok(mid)) lb=mid;
      else ub=mid;
    }
    cout<<lb<<endl;
  }

  return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 17524
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, string> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

ll N,M,K,L;
bool isfav[100010];
vector<ll> A,fav;
vector<string> S;
map<string,ll> id;
vector<ll> ord;

bool ok(ll X){
  if(X>K)return false;

  ll cnt=0;
  rep(i,K){
    if(isfav[ord[i]])cnt++;
  }
  if(X<=cnt)return true;

  ll add=X-cnt;
  ll rest=X-cnt;
  ll sum=0;
  for(ll i=K-1;i>=0;i--){
    if(!isfav[ord[i]]){
      rest--;
      if(rest==0){
        repl(j,K,N){
          if(isfav[ord[j]]){
            if(S[ord[i]]<S[ord[j]]) sum+=A[ord[i]]-A[ord[j]]+1;
            else sum+=A[ord[i]]-A[ord[j]];
            add--;
            if(add==0)break;
          }
        }
        break;
      }
    }
  }
  return sum<=L;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  while(1){
    A.clear(); S.clear(); fav.clear(); ord.clear();
    id.clear();
    cin>>N>>M>>K>>L;
    if(N==0)break;
    rep(i,N)isfav[i]=false;
    A.resize(N);
    S.resize(N);
    rep(i,N){
      string name;
      cin>>S[i]>>A[i];
      id[S[i]]=i;
    }
    rep(i,M){
      string name;
      cin>>name;
      fav.push_back(id[name]);
      isfav[id[name]]=true;
    }

    rep(i,N){
      ord.push_back(i);
    }
    sort(all(ord),[=](const ll& a,const ll& b){
      if(A[a]==A[b])return S[a]<S[b];
      else return A[a]>A[b];
    });

    //rep(i,N){
      //dbg(S[ord[i]]);
    //}

    ll lb=-1,ub=M+1;
    while(ub-lb>1){
      ll mid=(ub+lb)/2;
      if(ok(mid)) lb=mid;
      else ub=mid;
    }
    cout<<lb<<endl;
  }

  return 0;
}
accuracy: 0.25
time_ms: 770
memory_kb: 17352
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

const double PI = acos(-1);
const double EPS = 1e-15;
using ll = long long;
using ull = unsigned long long;
const int inf = 2e9;
const ll INF = 2e18;
const ll MOD = 1e9+7;
const ll MOD1 = 998244353;
typedef pair<ll,ll> P;

#define rep(i,a,b) for (int i = (a); i < (b); i++)
#define rrep(i,a,b) for (int i = (a); i >= (b); i--)
#define REP(i,n) rep(i,0,n)
#define RREP(i,n) rrep(i,n,0)
#define sz(s) (s).size()
#define pb push_back
#define fi first
#define se second
//#define mp make_pair

struct H {
  ll vote;
  string name;
  H(){vote = 0; name = "";}
  H(ll t, string c) {
    vote = t;
    name = c;
  }
  bool operator<(H e) const {
    if (vote == e.vote) return name > e.name;
    else return vote < e.vote;
  }
};

ll n,m,k,l;
vector<H> a;
vector<H> other, me;
set<string> st;

bool ok(ll K) {
  if (k < K) return 0;
  if (k - K >= sz(other)) return 1;
  H line = other[k - K];
  ll cnt = 0;
  REP(i,K) {
    ll vote = me[i].vote;
    string name = me[i].name;
    if (vote > line.vote) continue;
    else if (vote == line.vote) {
      if (name < line.name) continue;
      else cnt++;
    } else {
      cnt += line.vote - vote;
      if (name > line.name) cnt++;
    }
  }
//  cout << endl;
//  cout << "*" << line.vote << " " << line.name << endl;
//  cout << K << " " << cnt << " " << (cnt <= l? "ok":"no") <<endl;
  return cnt <= l;
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(0);

  while (cin >> n >> m >> k >> l, n) {
  other.clear();
  me.clear();
  st.clear();
  a.clear();

  REP(i,n) {
    string s;
    ll v;
    cin >> s >> v;
    a.pb(H(v,s));
  }
  sort(a.rbegin(),a.rend());
//
//  REP(i,n) {
//    cout << a[i].vote << " " << a[i].name << endl;
//  }

  REP(i,m) {
    string s;
    cin >> s;
    st.insert(s);
  }

  REP(i,n) {
    if (st.count(a[i].name)) {
      me.pb(a[i]);
    } else {
      other.pb(a[i]);
    }
  }

  other.pb({0,"zzz"});

  ll left = 0, r = m;
  while (left < r) {
    ll mid = (left + r + 1) / 2;
    if (ok(mid)) {
      left = mid;
    } else {
      r = mid - 1;
    }
  }
  cout << left << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 21104
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <utility>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#ifdef _DEBUG_
#define dump(val) cerr << __LINE__ << ":\t" << #val << " = " << (val) << endl
#else
#define dump(val)
#endif

using namespace std;

typedef long long int ll;
typedef pair<ll, string> P;

template<typename T>
vector<T> make_v(size_t a, T b) {
    return vector<T>(a, b);
}

template<typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

bool cmp(const P &p1, const P &p2) {
    if (p1.first != p2.first) {
        return p1.first > p2.first;
    } else {
        return p1.second < p2.second;
    }
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int N, M, K, L;
    while (cin >> N >> M >> K >> L, N) {

        vector<P> anime(N);
        vector<P> fav(M);
        {
            map<string, ll> mp;
            REP(i, 0, N) {
                cin >> anime[i].second >> anime[i].first;
                mp[anime[i].second] = anime[i].first;
            }

            REP(i, 0, M) {
                cin >> fav[i].second;
                fav[i].first = mp[fav[i].second];
            }
        }
        sort(anime.begin(), anime.end(), cmp);
        sort(fav.begin(), fav.end(), cmp);
        if (N == K) {
            cout << M << endl;
            continue;
        }

        int l = 0, r = min(K, M);
        int ans = 0;
        while (l <= r) {
            auto cp = anime;
            int mid = (l + r) / 2;
            ll sum = 0;
            REP (i, 0, mid) {
                int p1 = i, p2 = K - mid + i;
                if (cmp(cp[p2], fav[p1])) {
                    sum += cp[p2].first - fav[p1].first;
                    sum += (cp[p2].second < fav[p1].second);
                    swap(cp[p2], cp[p2 + 1]);
                } 
            }
            if (sum <= L) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        cout << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 22708
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <utility>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#ifdef _DEBUG_
#define dump(val) cerr << __LINE__ << ":\t" << #val << " = " << (val) << endl
#else
#define dump(val)
#endif

using namespace std;

typedef long long int ll;
typedef pair<ll, string> P;

template<typename T>
vector<T> make_v(size_t a, T b) {
    return vector<T>(a, b);
}

template<typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

bool cmp(const P &p1, const P &p2) {
    if (p1.first != p2.first) {
        return p1.first > p2.first;
    } else {
        return p1.second < p2.second;
    }
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int N, M, K, L;
    while (cin >> N >> M >> K >> L, N) {

        vector<P> anime(N);
        vector<P> fav(M);
        {
            map<string, ll> mp;
            REP(i, 0, N) {
                cin >> anime[i].second >> anime[i].first;
                mp[anime[i].second] = anime[i].first;
            }

            REP(i, 0, M) {
                cin >> fav[i].second;
                fav[i].first = mp[fav[i].second];
            }
        }
        sort(anime.begin(), anime.end(), cmp);
        sort(fav.begin(), fav.end(), cmp);
        int l = 0, r = min(K, M);
        int ans = 0;
        while (l <= r) {
            int mid = (l + r) / 2;
            ll sum = 0;
            REP (i, 0, mid) {
                int p1 = mid - i - 1, p2 = K - 1 - i;
                if (anime[p2].first >= fav[p1].first) {
                    sum += anime[p2].first - fav[p1].first;
                    sum += (anime[p2].second < fav[p1].second);
                } else {
                    break;
                }
            }
            if (sum <= L) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        cout << ans << endl;
    }

    return 0;
}
accuracy: 0.25
time_ms: 830
memory_kb: 21052
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <functional>
#include <map>
#include <climits>
#include <stack>
#include <string>
#include <random>
#include<set>
struct Vote {
	std::string name;
	int vote;
	bool operator<(const Vote &that) const {
		return (vote == that.vote) ? name > that.name : vote < that.vote;
	}
	bool operator==(const Vote &that) const {
		return vote == that.vote && name == that.name;
	}
	bool operator>(const Vote &that) const {
		return (vote == that.vote) ? name < that.name : vote > that.vote;
	}
};
bool can_take(const std::vector<Vote> &favorite, const Vote vote, int rest_vote, const int count) {
	for (auto i = favorite.size() - count; i < favorite.size(); ++i) {
		if (favorite[i] < vote) {
			if (favorite[i].name < vote.name) {
				rest_vote -= vote.vote - favorite[i].vote;
			}
			else {
				rest_vote -= vote.vote - favorite[i].vote + 1;
			}
			if (rest_vote < 0) return false;
		}
		else {
			return true;
		}
	}
	return true;
}
bool can_take(const std::vector<Vote> &fav, const std::vector<Vote> &no_chara, const int k, const int l, const int count) {
	auto else_count = k - count;
	if (else_count >= no_chara.size()) return true;
	else {
		return can_take(fav, no_chara[no_chara.size() - else_count - 1], l, count);
	}
}

void solve() {
	int n, m, k, l;
	std::cin >> n >> m >> k >> l;
	if (n == 0) return;
	std::vector<Vote> elseC;
	std::vector<Vote> favC;
	{
		std::map<std::string, int> estimated;
		std::string name; int vote;
		for (auto i = 0; i < n; ++i) {
			std::cin >> name >> vote;
			estimated.insert(std::make_pair(name, vote));
		}
		for (auto i = 0; i < m; ++i) {
			std::cin >> name;
			favC.push_back(Vote{ name, estimated[name] });
			estimated.erase(name);
		}
		for (const auto &pair : estimated) {
			elseC.push_back(Vote{ pair.first, pair.second });
		}
		std::sort(elseC.begin(), elseC.end());
		std::sort(favC.begin(), favC.end());
	}
	int left = 0;
	int right = std::min(m, k);
	while (left < right) {
		auto mid = (left + right + 1) / 2;
		if (can_take(favC, elseC, k, l, mid)) {
			left = mid;
		}
		else {
			right = mid - 1;
		}
	}
	std::cout << right << std::endl;
	solve();

}

int main() {
	solve();
}
/*



*/
accuracy: 1
time_ms: 1780
memory_kb: 65424
final_rank: 11

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100001

map<string,int> MAP;

struct Info{
	bool operator<(const struct Info &arg) const{
		return value > arg.value;
	}
	int value;
	string name;
	bool is_favorite;
};

int N,M,K,L;
int ally[NUM],enemy[NUM];
Info info[NUM];



bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

bool is_OK(int num){

	int sum = 0;

	if(ally[num-1] <= K-1)return true;

	int base_loc = enemy[K-num];

	for(int i = 0; i < num; i++){
		if(info[ally[i]].value > info[base_loc].value){
			sum += 0;
		}else if(info[ally[i]].value == info[base_loc].value){
			if(info[ally[i]].name < info[base_loc].name){
				sum += 0;
			}else{
				sum += 1;
			}
		}else{
			if(info[ally[i]].name < info[base_loc].name){
				sum += info[base_loc].value-info[ally[i]].value;
			}else{
				sum += info[base_loc].value-info[ally[i]].value+1;
			}
		}
		if(sum > L)return false;
	}
	return true;
}


void func(){

	MAP.clear();

	char buf[11];

	for(int i = 0; i < N; i++){
		scanf("%s %d",buf,&info[i].value);
		info[i].name = buf;
		info[i].is_favorite = false;
		MAP[info[i].name] = i;
	}

	string name;
	for(int loop = 0; loop < M; loop++){
		scanf("%s",buf);
		name = buf;
		info[MAP[name]].is_favorite = true;
	}

	sort(info,info+N);

	for(int i = 0; i < NUM; i++){
		ally[i] = BIG_NUM;
		enemy[i] = BIG_NUM;
	}

	int ally_index = 0,enemy_index = 0;

	for(int i = 0; i < N;i++){
		if(info[i].is_favorite){
			ally[ally_index++] = i;
		}else{
			enemy[enemy_index++] = i;
		}
	}


	int left = 0,right = min(K,M),m = (left+right)/2;
	int ans = 0;

	while(left <= right){
		if(is_OK(m)){
			ans = m;
			left = m+1;
		}else{
			right = m-1;
		}
		m = (left+right)/2;
	}
	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d %d %d",&N,&M,&K,&L);
		if(N == 0 && M == 0 && K == 0 && L == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 760
memory_kb: 17336
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <iterator>
#include <functional>
#include <utility>
#include <algorithm>
#include <numeric>
#include <typeinfo>
 
using namespace std;
 
#define dump(n) cerr<<"# "<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair
 
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;
 
typedef pair<int,string> pis;
 
bool cmp(const pii& a,const pii& b)
{
    return a.first==b.first?a.second<b.second:a.first>b.first;
}
 
bool ok(vector<pii>& favs,vector<pii>& oths,int k,int l,int num)
{
    if(oths.size()<=k-num)
        return true;
     
    ll need=0;
    rep(i,num){
        if(favs[i].first>oths[k-num].first)
            continue;
        else{
            int diff=oths[k-num].first-favs[i].first;
            bool after=favs[i].second>oths[k-num].second;
            need+=diff+after;
        }
    }
    return need<=l;
}
 
void solve(vs& names,vi& votes,vs& fnames,int k,int l)
{
    int n=names.size(),m=fnames.size();
     
    vector<pii> favs,oths; // vote,id
    {
        map<string,int> ma;
        rep(i,n)
            ma[names[i]]=0;
        {int i=0; foreach(it,ma)
            it->second=i++;
        }
        vi isfav(n);
        rep(i,m)
            isfav[ma[fnames[i]]]=1;
        rep(i,n){
            vector<pii>& chrs=isfav[ma[names[i]]]?favs:oths;
            chrs.push_back(mp(votes[i],ma[names[i]]));
        }
    }
     
    sort(allof(favs),cmp);
    sort(allof(oths),cmp);
     
    int left=0,right=1+min(m,k);
    while(right-left>1){
        int mid=(left+right)/2;
        if(ok(favs,oths,k,l,mid))
            left=mid;
        else
            right=mid;
    }
     
    cout<<left<<endl;
}
 
int main()
{
    for(int n,m,k,l;scanf("%d%d%d%d",&n,&m,&k,&l),n|m|k|l;){
        vs names(n);
        vi votes(n);
        for(int i=0;i<n;i++){
            char tmp[11];
            scanf("%s%d",tmp,&votes[i]);
            names[i]=tmp;
        }
        vs favs(m);
        rep(i,m){
            char tmp[11];
            scanf("%s",tmp);
            favs[i]=tmp;
        }
        solve(names,votes,favs,k,l);
    }
     
    return 0;
}
accuracy: 1
time_ms: 1160
memory_kb: 22272
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, string> P;

struct Chara
{
  string name;  
  int x;
  Chara(){}
  Chara(string name, int x):name(name), x(x){}
  bool operator < (const Chara& c) const {
    return x != c.x ? x > c.x : name < c.name;
  }
};

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int N, M, K, L;
set<string> favname;
vector<Chara> dic, fav, unf;

bool check(int k)
{
  if(unf.size() < K-k+1) return true;
  int l = 0;
  for(int i = 0; i < k; i++) {
    l += max(0LL, unf[K-k].x - fav[i].x + (fav[i].name > unf[K-k].name));
  }
  return l <= L;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> N >> M >> K >> L, N) {
    dic.clear();
    for(int i = 0; i < N; i++) {
      string name; int x;          
      cin >> name >> x;
      dic.push_back(Chara(name, x));
    }
    favname.clear();
    for(int i = 0; i < M; i++) {
      string name; cin >> name;
      favname.insert(name);
    }
    fav.clear();
    unf.clear();
    for(auto a : dic) {
      if(favname.find(a.name) != favname.end()) fav.push_back(a);
      else unf.push_back(a);
    }
    sort(all(fav));
    sort(all(unf));
    int lb = 0, ub = min(M, K) + 1;
    while(lb + 1 < ub) {
      int mb = (lb + ub) / 2;
      if(check(mb)) lb = mb;
      else ub = mb;
    }
    cout << lb << endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 790
memory_kb: 26200
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, string> P;

struct Chara
{
  string name;  
  int x;
  Chara(){}
  Chara(string name, int x):name(name), x(x){}
  bool operator < (const Chara& c) const {
    return x != c.x ? x > c.x : name < c.name;
  }
};

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int N, M, K, L;
set<string> favname;
vector<Chara> dic, fav, unf;



bool check(int k)
{
  if(unf.size() < K-k+1) return true;
  int l = 0;
  for(int i = 0; i < k; i++) {
    l += max(0LL, unf[K-k].x - fav[i].x);
    if(fav[i].name > unf[K-k].name) l++;    
  }
  return l <= L;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> N >> M >> K >> L, N) {
    dic.clear();
    for(int i = 0; i < N; i++) {
      string name; int x;          
      cin >> name >> x;
      dic.push_back(Chara(name, x));
    }
    favname.clear();
    for(int i = 0; i < M; i++) {
      string name; cin >> name;
      favname.insert(name);
    }
    fav.clear();
    unf.clear();
    for(auto a : dic) {
      if(favname.find(a.name) != favname.end()) fav.push_back(a);
      else unf.push_back(a);
    }
    sort(all(fav));
    sort(all(unf));
    int lb = 0, ub = min(M, K) + 1;
    while(lb + 1 < ub) {
      int mb = (lb + ub) / 2;
      if(check(mb)) lb = mb;
      else ub = mb;
    }
    cout << lb << endl;
  }
  
  return 0;
}
accuracy: 0.25
time_ms: 650
memory_kb: 26200
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, string> P;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int N, M, K, L;
set<string> favname;
vector<P> dic, fav, unf;

bool check(int k)
{
  if(unf.size() < K-k+1) return true;
  int l = 0;
  for(int i = 0; i < k; i++) {
    l += max(0LL, fav[i].first - unf[K-k].first);
    if(fav[i].second > unf[K-k].second) l++;    
  }
  return l <= L;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> N >> M >> K >> L, N) {
    dic.clear();
    for(int i = 0; i < N; i++) {
      string name; int x;          
      cin >> name >> x;
      dic.push_back(P(-x, name));
    }
    favname.clear();
    for(int i = 0; i < M; i++) {
      string name; cin >> name;
      favname.insert(name);
    }
    fav.clear();
    unf.clear();
    for(auto a : dic) {
      if(favname.find(a.second) != favname.end()) fav.push_back(a);
      else unf.push_back(a);
    }
    sort(all(fav));
    sort(all(unf));
    int lb = 0, ub = min(M, K) + 1;
    while(lb + 1 < ub) {
      int mb = (lb + ub) / 2;
      if(check(mb)) lb = mb;
      else ub = mb;
    }
    cout << lb << endl;
  }
  
  return 0;
}
accuracy: 0.25
time_ms: 640
memory_kb: 26296
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

//#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, string> P;

//const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int N, M, K, L;
set<string> favname;
vector<P> dic, fav, unf;

bool check(int k)
{
  if(unf.size() < K-k+1) return true;
  int l = 0;
  for(int i = 0; i < k; i++) {
    l += max(0, fav[i].first - unf[K-k].first);
    if(fav[i].second > unf[K-k].second) l++;    
  }
  return l <= L;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> N >> M >> K >> L, N) {
    dic.clear();
    for(int i = 0; i < N; i++) {
      string name; int x;          
      cin >> name >> x;
      dic.push_back(P(-x, name));
    }
    favname.clear();
    for(int i = 0; i < M; i++) {
      string name; cin >> name;
      favname.insert(name);
    }
    fav.clear();
    unf.clear();
    for(auto a : dic) {
      if(favname.find(a.second) != favname.end()) fav.push_back(a);
      else unf.push_back(a);
    }
    sort(all(fav));
    sort(all(unf));
    int lb = 0, ub = min(M, K) + 1;
    while(lb + 1 < ub) {
      int mb = (lb + ub) / 2;
      if(check(mb)) lb = mb;
      else ub = mb;
    }
    cout << lb << endl;
  }
  
  return 0;
}
accuracy: 0.25
time_ms: 640
memory_kb: 26232
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, string> P;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

int N, M, K, L;
vector<P> fav;
vector<P> unf;

bool check(int k)
{
  if(unf.size() < K-k+1) return true;
  int l = 0;
  for(int i = 0; i < k; i++) {
    if(fav[i].first != unf[K-k].first) {
      l += max(0LL, fav[i].first - unf[K-k].first);
    } else if(fav[i].second > unf[K-k].second) {
      l++;
    }
  }
  return l <= L;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> N >> M >> K >> L, N) {
    unordered_map<string, int> dic;
    for(int i = 0; i < N; i++) {
      string name; int x;          
      cin >> name >> x;
      dic[name] = -x;
    }
    set<string> favname;
    for(int i = 0; i < M; i++) {
      string name; cin >> name;
      favname.insert(name);
    }
    fav.clear();
    unf.clear();
    for(auto a : dic) {
      if(favname.find(a.first) != favname.end()) fav.push_back(P(a.second, a.first));
      else unf.push_back(P(a.second, a.first));
    }
    sort(all(fav));
    sort(all(unf));
    int lb = 0, ub = M+1;
    while(lb + 1 < ub) {
      int mb = (lb + ub) / 2;
      if(check(mb)) lb = mb;
      else ub = mb;
    }
    cout << lb << endl;
  }
  
  return 0;
}
accuracy: 0.25
time_ms: 980
memory_kb: 29580
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;


struct BinaryIndexedTree
{
  vector< int > data;

  BinaryIndexedTree(int sz)
  {
    data.assign(++sz, 0);
  }

  int sum(int k)
  {
    int ret = 0;
    for(++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }

  void add(int k, int x)
  {
    for(++k; k < data.size(); k += k & -k) data[k] += x;
  }
};

int main()
{
  long long N, M, K, L;
  char buff[12];

  while(scanf("%lld %lld %lld %lld", &N, &M, &K, &L), N) {

    vector< pair< int, string > > data(N);
    vector< int > toint(N);
    vector< string > priority(N);
    unordered_map< string, int > vv;
    vector< bool > like(N, false);

    for(int i = 0; i < N; i++) {
      int x;
      scanf(" %s %d", buff, &x);
      data[i] = make_pair(-x, buff);
      priority[i] = data[i].second;
    }
    sort(begin(priority), end(priority));
    sort(begin(data), end(data));


    for(int i = 0; i < N; i++) {
      toint[i] = lower_bound(begin(priority), end(priority), data[i].second) - begin(priority);
      vv[data[i].second] = i;
      data[i].first *= -1;
    }

    for(int i = 0; i < M; i++) {
      scanf("%s", buff);
      like[vv[buff]] = true;
    }

    BinaryIndexedTree bit(N);

    long long right = K, bottom = 0, up = 0;
    long long sz = 0, ret = 0, pre = -1;

    for(int i = 0; i < K; i++) {
      ret += like[i];
    }

    for(int i = K - 1; i >= 0; i--) {
      if(!like[i]) {
        while(right < N && !like[right]) ++right;
        if(right == N) break;
        L -= data[i].first - data[right].first;
        if(~pre) {
          L -= bottom * (data[i].first - pre);
          L -= up * (data[i].first - pre - 1); // kore sugoi
        }
        bit.add(toint[right], 1);
        bottom = bit.sum(toint[i]);
        up = bit.sum(N - 1) - bottom;
        pre = data[i].first;
        sz = 0;
        L -= up;
        if(L < 0) break;
        ++ret;
        ++right;
      } else {
        if(i == 0) break;
        bit.add(toint[i], 1);
        L -= ++sz * (data[i - 1].first - data[i].first);
      }
    }

    printf("%lld\n", ret);
  }

}
accuracy: 1
time_ms: 810
memory_kb: 16472
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;


struct BinaryIndexedTree
{
  vector< int > data;

  BinaryIndexedTree(int sz)
  {
    data.assign(++sz, 0);
  }

  int sum(int k)
  {
    int ret = 0;
    for(++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }

  void add(int k, int x)
  {
    for(++k; k < data.size(); k += k & -k) data[k] += x;
  }
};

int main()
{
  long long N, M, K, L;
  char buff[12];

  while(scanf("%lld %lld %lld %lld", &N, &M, &K, &L), N) {

    vector< pair< int, string > > data(N);
    vector< int > toint(N);
    vector< string > priority(N);
    unordered_map< string, int > vv;
    vector< bool > like(N, false);

    for(int i = 0; i < N; i++) {
      int x;
      scanf(" %s %d", buff, &x);
      data[i] = make_pair(-x, buff);
      priority[i] = data[i].second;
    }
    sort(begin(priority), end(priority));
    sort(begin(data), end(data));


    for(int i = 0; i < N; i++) {
      toint[i] = lower_bound(begin(priority), end(priority), data[i].second) - begin(priority);
      vv[data[i].second] = i;
      data[i].first *= -1;
    }

    for(int i = 0; i < M; i++) {
      scanf("%s", buff);
      like[vv[buff]] = true;
    }

    BinaryIndexedTree bit(N);

    long long right = K, bottom = 0, up = 0;
    long long sz = 0, ret = 0, pre = -1;

    for(int i = 0; i < K; i++) {
      ret += like[i];
    }

    for(int i = K - 1; i >= 0; i--) {
      if(!like[i]) {
        while(right < N && !like[right]) ++right;
        if(right == N) break;

        if(data[i].first == data[pre].first) {
//          cerr << "foo" << endl;
// ???????????¨???????????????????????????

        }
        L -= data[i].first - data[right].first;
        if(~pre) {
          L -= bottom * (data[i].first - data[pre].first);
          L -= up * (data[i].first - data[pre].first - 1);
        }
//        assert(bottom * (data[i].first - data[pre].first) >= 0);
//        assert(up * (data[i].first - data[pre].first - 1) >= 0);

        bit.add(toint[right], 1);

        bottom = bit.sum(toint[i]);
        up = bit.sum(N - 1) - bottom;
        pre = i;
        sz = 0;

        L -= up;


        if(L < 0) break;
        ++ret;
        ++right;
      } else {
        if(i == 0) break;
        bit.add(toint[i], 1);
        L -= ++sz * (data[i - 1].first - data[i].first);
      }
    }

    printf("%lld\n", ret);
  }

}
accuracy: 1
time_ms: 800
memory_kb: 16544
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;


struct BinaryIndexedTree
{
  vector< int > data;

  BinaryIndexedTree(int sz)
  {
    data.assign(++sz, 0);
  }

  int sum(int k)
  {
    int ret = 0;
    for(++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }

  void add(int k, int x)
  {
    for(++k; k < data.size(); k += k & -k) data[k] += x;
  }
};

int main()
{
  long long N, M, K, L;
  char buff[12];

  while(scanf("%lld %lld %lld %lld", &N, &M, &K, &L), N) {

    vector< pair< int, string > > data(N);
    vector< int > toint(N);
    vector< string > priority(N);
    unordered_map< string, int > vv;
    vector< bool > like(N, false);

    for(int i = 0; i < N; i++) {
      int x;
      scanf(" %s %d", buff, &x);
      data[i] = make_pair(-x, buff);
      priority[i] = data[i].second;
    }
    sort(begin(priority), end(priority));
    sort(begin(data), end(data));


    for(int i = 0; i < N; i++) {
      toint[i] = lower_bound(begin(priority), end(priority), data[i].second) - begin(priority);
      vv[data[i].second] = i;
      data[i].first *= -1;
    }

    for(int i = 0; i < M; i++) {
      scanf("%s", buff);
      like[vv[buff]] = true;
    }

    BinaryIndexedTree bit(N);

    long long right = K, bottom = 0, up = 0;
    long long sz = 0, ret = 0, pre = 0;

    for(int i = 0; i < K; i++) {
      ret += like[i];
    }

    for(int i = K - 1; i >= 0; i--) {
      if(!like[i]) {
        while(right < N && !like[right]) ++right;
        if(right == N) break;
        bit.add(toint[right], 1);

        L -= data[i].first - data[right].first;
        L -= bottom * (data[i].first - pre);
        L -= up * (data[i].first - pre - 1);

        bottom = bit.sum(toint[i]);
        up = bit.sum(N - 1) - bottom;
        pre = data[right].first;
        sz = 0;

        L -= up;
        if(L < 0) break;
        ++ret;
      } else {
        if(i == 0) break;
        bit.add(toint[i], 1);
        L -= ++sz * (data[i - 1].first - data[i].first);
      }
    }

    printf("%lld\n", ret);
  }

}
accuracy: 0.25
time_ms: 810
memory_kb: 16488
final_rank: 14

code_snippet: #include <iostream>
#include <map>
#include <vector>
#include <algorithm>

using namespace std;

struct P {
    int point;
    string name;

    P() {}
    P(int point, string name) : point{point}, name{name} {}

    bool operator < (const P& p) const {
        if (point != p.point) {
            return point > p.point;            
        }
        return name < p.name;
    }
};

bool c(int X, int K, int L, const vector<P>& info, const vector<int>& p)
{
    int sum = 0;
    int rnk = K - X;
    for (int i = 0; i < X; i++) {
        if (p[i] <= rnk) {
            rnk = min(rnk + 1, K);
            continue;
        }

        if (info[p[i]].name < info[rnk].name) {        
            sum += info[rnk].point - info[p[i]].point;
        } else {
            sum += info[rnk].point - info[p[i]].point + 1;
        }
        if (sum > L) return 0;
    }
    return (sum <= L);
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N, M, K, L;
    while (cin >> N >> M >> K >> L, N > 0) {
        string name;
        int point;
        vector<P> info;
        for (int i = 0; i < N; i++) {
            cin >> name >> point;
            info.emplace_back(point, name);
        }

        sort(info.begin(), info.end());
        
        map<string, int> num;
        for (int i = 0; i < N; i++) {
            num[info[i].name] = i;
        }
        
        vector<int> p(M);
        string fav;
        for (int i = 0; i < M; i++) {
            cin >> fav;
            p[i] = num[fav];
        }

        sort(p.begin(), p.end());

        int l = 0, r = min(K, M);
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (c(mid, K, L, info, p)) {
                l = mid;
            } else {
                r = mid;
            }
        }

        if (c(r, K, L, info, p)) {
            cout << r << endl;
        } else {
            cout << l << endl;
        }
    }        
    return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 15760
final_rank: 3