Problem:
Programming Contest II
Every year, Byakko University holds a programming contest. The contest starts with all teams having zero points, and points are added according to their answers. In this contest, the teams are ranked in order of their scores. When the total number of teams is
N
, each team is assigned a number from 1 to
N
. If the teams have the same score, the team with the smaller number will be ranked higher.
Byakko University is developing a ranking system for spectators to make the contest more exciting. As a development team member, you are asked to make a program that is part of this system.
Make a program to update the scores, and report the numbers and scores of the teams in a given rank, according to the given command.
Input
The input is given in the following format.
N
C
command
1
command
2
:
command
C
In the first line, the number of teams
N
(2 ≤
N
≤ 100000) and the number of commands
C
(1 ≤
C
≤ 100000) are given. In the following
C
lines, commands are given. Each command is given in the following format.
0
t
p
or
1
m
When the first number is 0, it indicates an update command, and when it is 1, it indicates a report command. In the update command, add the score
p
(1 ≤
p
≤ 10
9
), given as an integer, to the team with the given number
t
(1 ≤
t
≤
N
). In the report command, report the number and score of the team in a given rank
m
(1 ≤
m
≤
N
). However, the report command must appear at least once.
Output
For each report command, output the number and score of the team in a given rank in a line, separated by space.
Sample Input 1
3 11
0 2 5
0 1 5
0 3 4
1 1
1 2
1 3
0 3 2
1 1
0 2 1
1 2
1 3
Sample Output 1
1 5
2 5
3 4
3 6
3 6
1 5
Sample Input 2
5 2
1 1
1 2
Sample Output 2
1 0
2 0

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#include <iomanip>
#include <numbers>
#include <cassert>
#include <numeric>
#ifdef _MSC_VER
#include <intrin.h>
#endif
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pint = pair<int, int>;
using pll = pair<ll, ll>;
template<typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
template<typename T>
bool chmax(T & a, const T & b) { if (a < b) { a = b; return true; } return false; }
template<typename T>
bool chmin(T & a, const T & b) { if (a > b) { a = b; return true; } return false; }
const int inf = 1e9;
const ll linf = 1e18;
const int dy[] = { 0,0,1,-1 }, dx[] = { 1,-1,0,0 };
namespace atcoder {

    namespace internal {

#ifndef _MSC_VER
        template <class T>
        using is_signed_int128 =
            typename std::conditional<std::is_same<T, __int128_t>::value ||
            std::is_same<T, __int128>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int128 =
            typename std::conditional<std::is_same<T, __uint128_t>::value ||
            std::is_same<T, unsigned __int128>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using make_unsigned_int128 =
            typename std::conditional<std::is_same<T, __int128_t>::value,
            __uint128_t,
            unsigned __int128>;

        template <class T>
        using is_integral = typename std::conditional<std::is_integral<T>::value ||
            is_signed_int128<T>::value ||
            is_unsigned_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_signed_int = typename std::conditional<(is_integral<T>::value&&
            std::is_signed<T>::value) ||
            is_signed_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int =
            typename std::conditional<(is_integral<T>::value&&
                std::is_unsigned<T>::value) ||
            is_unsigned_int128<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using to_unsigned = typename std::conditional<
            is_signed_int128<T>::value,
            make_unsigned_int128<T>,
            typename std::conditional<std::is_signed<T>::value,
            std::make_unsigned<T>,
            std::common_type<T>>::type>::type;

#else

        template <class T> using is_integral = typename std::is_integral<T>;

        template <class T>
        using is_signed_int =
            typename std::conditional<is_integral<T>::value&& std::is_signed<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using is_unsigned_int =
            typename std::conditional<is_integral<T>::value&&
            std::is_unsigned<T>::value,
            std::true_type,
            std::false_type>::type;

        template <class T>
        using to_unsigned = typename std::conditional<is_signed_int<T>::value,
            std::make_unsigned<T>,
            std::common_type<T>>::type;

#endif

        template <class T>
        using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

        template <class T>
        using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

        template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

    }

}
namespace atcoder {

    template <class T> struct fenwick_tree {
        using U = internal::to_unsigned_t<T>;

    public:
        fenwick_tree() : _n(0) {}
        fenwick_tree(int n) : _n(n), data(n) {}

        void add(int p, T x) {
            assert(0 <= p && p < _n);
            p++;
            while (p <= _n) {
                data[p - 1] += U(x);
                p += p & -p;
            }
        }

        T sum(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            return sum(r) - sum(l);
        }

    private:
        int _n;
        std::vector<U> data;

        U sum(int r) {
            U s = 0;
            while (r > 0) {
                s += data[r - 1];
                r -= r & -r;
            }
            return s;
        }
    };

}
using namespace atcoder;
template<typename T>
void normalize(vector<T>& ary) {
    sort(ary.begin(), ary.end());
    ary.erase(unique(ary.begin(), ary.end()), ary.end());
}
template<typename T>
int comp(const T& num, const vector<T>& ary) {
    return lower_bound(ary.begin(), ary.end(), num) - ary.begin();
}
int main() {
    int n, c; cin >> n >> c;
    vector<vector<int>> qs;
    vector<ll> point(n);
    vector<ll> ps(1);
    rep(i, c) {
        int j; cin >> j;
        if (j == 0) {
            int t, p; cin >> t >> p;
            t--;
            point[t] += p;
            ps.push_back(point[t]);
            qs.push_back({ j,t,p });
        }
        else {
            int m; cin >> m;
            qs.push_back({ j,m });
        }
    }
    normalize(ps);
    vector<vector<int>> idx(ps.size());
    rep(i, n)idx[0].push_back(i);
    rep(i, n)point[i] = 0;
    rep(i, c)if (qs[i][0] == 0) {
        int t = qs[i][1], p = qs[i][2];
        point[t] += p;
        idx[comp(point[t], ps)].push_back(t);
    }
    rep(i, ps.size())normalize(idx[i]);
    fenwick_tree<int> fwAll(ps.size());
    vector<fenwick_tree<int>> fw(ps.size());
    rep(i, ps.size())fw[i] = fenwick_tree<int>(idx[i].size());
    fwAll.add(0, n);
    rep(i, n)fw[0].add(i, 1);
    rep(i, n)point[i] = 0;
    rep(i, c) {
        if (qs[i][0] == 0) {
            int t = qs[i][1], p = qs[i][2];
            int cp = comp(point[t], ps);
            int ct = comp(t, idx[cp]);
            fwAll.add(cp, -1);
            fw[cp].add(ct, -1);
            point[t] += p;
            cp = comp(point[t], ps);
            ct = comp(t, idx[cp]);
            fwAll.add(cp, 1);
            fw[cp].add(ct, 1);
        }
        else {
            int m = qs[i][1];
            int left = 0, right = ps.size();
            while (left + 1 < right) {
                int mid = (left + right) / 2;
                if (fwAll.sum(mid, ps.size()) >= m)left = mid;
                else right = mid;
            }
            m -= fwAll.sum(left + 1, ps.size());
            int left2 = 0, right2 = idx[left].size() - 1;
            while (left2 < right2) {
                int mid2 = (left2 + right2) / 2;
                if (fw[left].sum(0, mid2 + 1) >= m)right2 = mid2;
                else left2 = mid2 + 1;
            }
            printf("%d %lld\n", idx[left][left2] + 1, ps[left]);
        }
    }
}
accuracy: 1
time_ms: 60
memory_kb: 23656
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ld=long double;
#define fi first;
#define se second;
#define i128 __int128_t
#define all(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define si(a) (long)(a.size())
template<typename T>bool chmin(T&a,T b){return b<a?(a=b,1):0;}
template<typename T>bool chmax(T&a,T b){return b>a?(a=b,1):0;}
const int INF=1e9+100;
const long INFL=3e18+100;
struct _ {
   _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

int main(){
    int N,C;
    cin>>N>>C;
    vector<long> P(N,0);
    ordered_set<pair<long,int>> st;
    rep(i,N) st.insert({0, i});
    while(C--){
        int o;
        cin>>o;
        if(o==0){
            int t,p;
            cin>>t>>p;
            t--;
            st.erase({P[t], t});
            P[t]-=p;
            st.insert({P[t], t});
        }
        else{
            int m;
            cin>>m;
            m--;
            auto it=st.find_by_order(m);
            cout<<it->second+1<<" "<<-(it->first)<<"\n";
        }
    }

}
accuracy: 1
time_ms: 110
memory_kb: 10192
final_rank: 8

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

template <typename T>
using vc = vector<T>;
template <typename T>
using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
using mint = modint1000000007;
//    using mint = modint;
//    mint::set_mod(m);

template <class T>
using pq = priority_queue<T, vc<T>>;
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>;
//-----------------------------------

//-------------2.配列系--------------

using pii = pair<int, int>;
using pll = pair<long long, long long>;

#define rep(i, n) for (ll i = 0; i < (n); ++i)
template <class T>
istream &operator>>(istream &i, vc<T> &v) {
    rep(j, size(v)) i >> v[j];
    return i;
}

using ar2 = array<ll, 2>;

//----------------------------------

//--------3.コード短縮化とか---------
const double PI = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--)

#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else {                     \
        cout << "No" << endl;  \
    }  // if(a==b)YN;

#define vc_unique(v) v.erase(unique(v.begin(), v.end()), v.end());
#define vc_rotate(v) rotate(v.begin(), v.begin() + 1, v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(), v.end())

//-------------------------------

//---------4.グリッド系----------
vector<int> dx = {1, 0, -1, 0};  //  dx={1,1,0,-1,-1,-1,0,1};
vector<int> dy = {0, 1, 0, -1};  //  dy={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w = -1) {
    if (w == -1) {
        w = h;
    }
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_rotate(v)                                   \
    {                                                   \
        ll n = size(v);                                 \
        vvl nx(n, vl(n));                               \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    }  // 時計回りに90°回転
// #define vvl_rotate(v) {ll n = size(v);vvl
// nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_rotate(v)                                    \
    {                                                   \
        ll n = size(v);                                 \
        vs nx(n, string(n, '.'));                       \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    }  // 文字列版 時計回りに90°回転
// #define vs_rotate(v) {ll n = size(v);vs
// nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転

#define vvl_transpos(v)                         \
    {                                           \
        ll n = size(v);                         \
        vvl nx(n, vl(n));                       \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }
#define vs_transpos(v)                          \
    {                                           \
        ll n = size(v);                         \
        vs nx(n, string(n, '.'));               \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }

//--------------------------------

//-----------5.数学系--------------
#define euclid(x, y) ((x) * (x) + (y) * (y))  // ユークリッド距離 2乗のまま
#define manhattan(x1, x2, y1, y2) \
    (abs(x1 - x2) + abs(y1 - y2))  // マンハッタン距離 = |x1-x2|+|y1-y2|

template <class T>
T tousa_sum1(T l, T d, T r) {  // 初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template <class T>
T tousa_sum2(T a, T d, T n) {  // 初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {  // 初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
mint touhi_sum(mint a, mint r,
               ll n) {  // 初項,公比,項数で等比数列の総和を求める
    if (r == 1) {
        return a * n;
    }
    mint bunsi = a * (r.pow(n) - mint(1));
    mint bunbo = r - 1;
    return bunsi / bunbo;
}

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------

//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

#define print_vec(v)                   \
    {                                  \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << " "; \
        cout << endl;                  \
    }  // 一次元配列を出力する(改行なし)

#define vc_cout(v)                      \
    {                                   \
        ll n = size(v);                 \
        rep(i, n) cout << v[i] << endl; \
    }  // 一次元配列を出力する(改行あり)
#define vv_cout(v)                                         \
    {                                                      \
        ll n = size(v);                                    \
        rep(i, n) {                                        \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    }  // 二次元配列を出力する
//----------------------------------------------
// Segment Tree
template <class Monoid>
struct SegmentTree {
    using Func = function<Monoid(Monoid, Monoid)>;

    // core member
    int N;
    Func OP;
    Monoid IDENTITY;

    // inner data
    int log, offset;
    vector<Monoid> dat;

    // constructor
    SegmentTree() {}
    SegmentTree(int n, const Func &op, const Monoid &identity) {
        init(n, op, identity);
    }
    SegmentTree(const vector<Monoid> &v, const Func &op,
                const Monoid &identity) {
        init(v, op, identity);
    }
    void init(int n, const Func &op, const Monoid &identity) {
        N = n;
        OP = op;
        IDENTITY = identity;
        log = 0, offset = 1;
        while (offset < N) ++log, offset <<= 1;
        dat.assign(offset * 2, IDENTITY);
    }
    void init(const vector<Monoid> &v, const Func &op, const Monoid &identity) {
        init((int)v.size(), op, identity);
        build(v);
    }
    void pull(int k) { dat[k] = OP(dat[k * 2], dat[k * 2 + 1]); }
    void build(const vector<Monoid> &v) {
        assert(N == (int)v.size());
        for (int i = 0; i < N; ++i) dat[i + offset] = v[i];
        for (int k = offset - 1; k > 0; --k) pull(k);
    }
    int size() const { return N; }
    Monoid operator[](int i) const { return dat[i + offset]; }

    // update A[i], i is 0-indexed, O(log N)
    void set(int i, const Monoid &v) {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] = v;
        while (k >>= 1) pull(k);
    }

    void add(int i, const Monoid &v) {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] += v;
        while (k >>= 1) pull(k);
    }

    // get [l, r), l and r are 0-indexed, O(log N)
    Monoid prod(int l, int r) {
        assert(0 <= l && l <= r && r <= N);
        Monoid val_left = IDENTITY, val_right = IDENTITY;
        l += offset, r += offset;
        for (; l < r; l >>= 1, r >>= 1) {
            if (l & 1) val_left = OP(val_left, dat[l++]);
            if (r & 1) val_right = OP(dat[--r], val_right);
        }
        return OP(val_left, val_right);
    }
    Monoid all_prod() { return dat[1]; }

    // get max r that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int max_right(const function<bool(Monoid)> f, int l = 0) {
        if (l == N) return N;
        l += offset;
        Monoid sum = IDENTITY;
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(OP(sum, dat[l]))) {
                while (l < offset) {
                    l = l * 2;
                    if (f(OP(sum, dat[l]))) {
                        sum = OP(sum, dat[l]);
                        ++l;
                    }
                }
                return l - offset;
            }
            sum = OP(sum, dat[l]);
            ++l;
        } while ((l & -l) != l);  // stop if l = 2^e
        return N;
    }

    // get min l that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int min_left(const function<bool(Monoid)> f, int r = -1) {
        if (r == 0) return 0;
        if (r == -1) r = N;
        r += offset;
        Monoid sum = IDENTITY;
        do {
            --r;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(OP(dat[r], sum))) {
                while (r < offset) {
                    r = r * 2 + 1;
                    if (f(OP(dat[r], sum))) {
                        sum = OP(dat[r], sum);
                        --r;
                    }
                }
                return r + 1 - offset;
            }
            sum = OP(dat[r], sum);
        } while ((r & -r) != r);
        return 0;
    }

    // debug
    friend ostream &operator<<(ostream &s, const SegmentTree &seg) {
        for (int i = 0; i < (int)seg.size(); ++i) {
            s << seg[i];
            if (i != (int)seg.size() - 1) s << " ";
        }
        return s;
    }
};

vector<int> compression(vector<pll> vec) {
    vector<pll> c = vec;
    sort(c.begin(), c.end());
    c.erase(unique(c.begin(), c.end()), c.end());

    vector<int> res(vec.size());
    for (int i = 0; i < vec.size(); i++) {
        res[i] = lower_bound(c.begin(), c.end(), vec[i]) - c.begin();
    }
    return res;
}

int k;
bool f(int x) { return x < k; }

void solve() { return; }
int op(int a, int b) { return a + b; }
int e = 0;
int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(10);

    int n, q;
    cin >> n >> q;

    vector<ll> s(n);
    vector<ll> v(q), p(q), m(q);

    rep(i, q) {
        int t;
        cin >> t;
        if (t == 0) {
            int idx, x;
            cin >> idx >> x, idx--;

            s[idx] += x;
            v[i] = s[idx];
            p[i] = idx;
        } else {
            int x;
            cin >> x;
            m[i] = x;
        }
    }

    vector<pll> vec(n + q);
    rep(i, n) vec[i] = {0, -i};
    rep(i, q) vec[n + i] = {v[i], -p[i]};

    // 座圧
    auto r = compression(vec);

    sort(all(vec));
    vc_unique(vec);
    int l = r.size();

    // 人iが対応する位置 (座圧後の値)
    vector<ll> pos(n);

    rep(i, n) pos[i] = n - i - 1;
    // セグ木上で二分探索
    SegmentTree<int> seg(l, op, e);
    rep(i, n) seg.set(i, 1);

    rep(i, q) {
        if (v[i]) {
            // idx -> 人
            int idx = p[i];
            seg.set(pos[idx], 0);

            pos[idx] = r[n + i];
            seg.set(pos[idx], 1);

        } else {
            k = m[i];
            int idx = seg.min_left(f);
            idx--;
            cout << -vec[idx].second + 1 << " " << vec[idx].first << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 16732
final_rank: 1

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

template <typename T>
using vc = vector<T>;
template <typename T>
using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
using mint = modint1000000007;
//    using mint = modint;
//    mint::set_mod(m);

template <class T>
using pq = priority_queue<T, vc<T>>;
template <class T>
using pq_g = priority_queue<T, vc<T>, greater<T>>;
//-----------------------------------

//-------------2.配列系--------------

using pii = pair<int, int>;
using pll = pair<long long, long long>;

#define rep(i, n) for (ll i = 0; i < (n); ++i)
template <class T>
istream &operator>>(istream &i, vc<T> &v) {
    rep(j, size(v)) i >> v[j];
    return i;
}

using ar2 = array<ll, 2>;

//----------------------------------

//--------3.コード短縮化とか---------
const double PI = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define drep(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define nfor(i, s, n) for (ll i = s; i < n; i++)
#define dfor(i, s, n) for (ll i = (s) - 1; i >= n; i--)

#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)

#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define YN                     \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else {                     \
        cout << "No" << endl;  \
    }  // if(a==b)YN;

#define vc_unique(v) v.erase(unique(v.begin(), v.end()), v.end());
#define vc_rotate(v) rotate(v.begin(), v.begin() + 1, v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(), v.end())

//-------------------------------

//---------4.グリッド系----------
vector<int> dx = {1, 0, -1, 0};  //  dx={1,1,0,-1,-1,-1,0,1};
vector<int> dy = {0, 1, 0, -1};  //  dy={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w = -1) {
    if (w == -1) {
        w = h;
    }
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_rotate(v)                                   \
    {                                                   \
        ll n = size(v);                                 \
        vvl nx(n, vl(n));                               \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    }  // 時計回りに90°回転
// #define vvl_rotate(v) {ll n = size(v);vvl
// nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_rotate(v)                                    \
    {                                                   \
        ll n = size(v);                                 \
        vs nx(n, string(n, '.'));                       \
        rep(i, n) rep(j, n) nx[j][n - i - 1] = v[i][j]; \
        swap(nx, v);                                    \
    }  // 文字列版 時計回りに90°回転
// #define vs_rotate(v) {ll n = size(v);vs
// nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転

#define vvl_transpos(v)                         \
    {                                           \
        ll n = size(v);                         \
        vvl nx(n, vl(n));                       \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }
#define vs_transpos(v)                          \
    {                                           \
        ll n = size(v);                         \
        vs nx(n, string(n, '.'));               \
        rep(i, n) rep(j, n) nx[j][i] = v[i][j]; \
        swap(nx, v);                            \
    }

//--------------------------------

//-----------5.数学系--------------
#define euclid(x, y) ((x) * (x) + (y) * (y))  // ユークリッド距離 2乗のまま
#define manhattan(x1, x2, y1, y2) \
    (abs(x1 - x2) + abs(y1 - y2))  // マンハッタン距離 = |x1-x2|+|y1-y2|

template <class T>
T tousa_sum1(T l, T d, T r) {  // 初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template <class T>
T tousa_sum2(T a, T d, T n) {  // 初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {  // 初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
mint touhi_sum(mint a, mint r,
               ll n) {  // 初項,公比,項数で等比数列の総和を求める
    if (r == 1) {
        return a * n;
    }
    mint bunsi = a * (r.pow(n) - mint(1));
    mint bunbo = r - 1;
    return bunsi / bunbo;
}

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------

//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

#define print_vec(v)                   \
    {                                  \
        ll n = size(v);                \
        rep(i, n) cout << v[i] << " "; \
        cout << endl;                  \
    }  // 一次元配列を出力する(改行なし)

#define vc_cout(v)                      \
    {                                   \
        ll n = size(v);                 \
        rep(i, n) cout << v[i] << endl; \
    }  // 一次元配列を出力する(改行あり)
#define vv_cout(v)                                         \
    {                                                      \
        ll n = size(v);                                    \
        rep(i, n) {                                        \
            rep(j, size(v[i])) { cout << v[i][j] << ' '; } \
            cout << endl;                                  \
        }                                                  \
    }  // 二次元配列を出力する
//----------------------------------------------
// Segment Tree
template <class Monoid>
struct SegmentTree {
    using Func = function<Monoid(Monoid, Monoid)>;

    // core member
    int N;
    Func OP;
    Monoid IDENTITY;

    // inner data
    int log, offset;
    vector<Monoid> dat;

    // constructor
    SegmentTree() {}
    SegmentTree(int n, const Func &op, const Monoid &identity) {
        init(n, op, identity);
    }
    SegmentTree(const vector<Monoid> &v, const Func &op,
                const Monoid &identity) {
        init(v, op, identity);
    }
    void init(int n, const Func &op, const Monoid &identity) {
        N = n;
        OP = op;
        IDENTITY = identity;
        log = 0, offset = 1;
        while (offset < N) ++log, offset <<= 1;
        dat.assign(offset * 2, IDENTITY);
    }
    void init(const vector<Monoid> &v, const Func &op, const Monoid &identity) {
        init((int)v.size(), op, identity);
        build(v);
    }
    void pull(int k) { dat[k] = OP(dat[k * 2], dat[k * 2 + 1]); }
    void build(const vector<Monoid> &v) {
        assert(N == (int)v.size());
        for (int i = 0; i < N; ++i) dat[i + offset] = v[i];
        for (int k = offset - 1; k > 0; --k) pull(k);
    }
    int size() const { return N; }
    Monoid operator[](int i) const { return dat[i + offset]; }

    // update A[i], i is 0-indexed, O(log N)
    void set(int i, const Monoid &v) {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] = v;
        while (k >>= 1) pull(k);
    }

    void add(int i, const Monoid &v) {
        assert(0 <= i && i < N);
        int k = i + offset;
        dat[k] += v;
        while (k >>= 1) pull(k);
    }

    // get [l, r), l and r are 0-indexed, O(log N)
    Monoid prod(int l, int r) {
        assert(0 <= l && l <= r && r <= N);
        Monoid val_left = IDENTITY, val_right = IDENTITY;
        l += offset, r += offset;
        for (; l < r; l >>= 1, r >>= 1) {
            if (l & 1) val_left = OP(val_left, dat[l++]);
            if (r & 1) val_right = OP(dat[--r], val_right);
        }
        return OP(val_left, val_right);
    }
    Monoid all_prod() { return dat[1]; }

    // get max r that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int max_right(const function<bool(Monoid)> f, int l = 0) {
        if (l == N) return N;
        l += offset;
        Monoid sum = IDENTITY;
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(OP(sum, dat[l]))) {
                while (l < offset) {
                    l = l * 2;
                    if (f(OP(sum, dat[l]))) {
                        sum = OP(sum, dat[l]);
                        ++l;
                    }
                }
                return l - offset;
            }
            sum = OP(sum, dat[l]);
            ++l;
        } while ((l & -l) != l);  // stop if l = 2^e
        return N;
    }

    // get min l that f(get(l, r)) = True (0-indexed), O(log N)
    // f(IDENTITY) need to be True
    int min_left(const function<bool(Monoid)> f, int r = -1) {
        if (r == 0) return 0;
        if (r == -1) r = N;
        r += offset;
        Monoid sum = IDENTITY;
        do {
            --r;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(OP(dat[r], sum))) {
                while (r < offset) {
                    r = r * 2 + 1;
                    if (f(OP(dat[r], sum))) {
                        sum = OP(dat[r], sum);
                        --r;
                    }
                }
                return r + 1 - offset;
            }
            sum = OP(dat[r], sum);
        } while ((r & -r) != r);
        return 0;
    }

    // debug
    friend ostream &operator<<(ostream &s, const SegmentTree &seg) {
        for (int i = 0; i < (int)seg.size(); ++i) {
            s << seg[i];
            if (i != (int)seg.size() - 1) s << " ";
        }
        return s;
    }
};

vector<int> compression(vector<pll> vec) {
    vector<pll> c = vec;
    sort(c.begin(), c.end());
    c.erase(unique(c.begin(), c.end()), c.end());

    vector<int> res(vec.size());
    for (int i = 0; i < vec.size(); i++) {
        res[i] = lower_bound(c.begin(), c.end(), vec[i]) - c.begin();
    }
    return res;
}

int k;
bool f(int x) { return x < k; }

void solve() { return; }
int op(int a, int b) { return a + b; }
int e = 0;
int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(10);

    int n, q;
    cin >> n >> q;

    vector<ll> s(n);
    vector<ll> v(q), p(q), m(q);

    rep(i, q) {
        int t;
        cin >> t;
        if (t == 0) {
            int idx, x;
            cin >> idx >> x, idx--;

            s[idx] += x;
            v[i] = s[idx];
            p[i] = idx;
        } else {
            int x;
            cin >> x;
            m[i] = x;
        }
    }

    vector<pll> vec(n + q);
    rep(i, n) vec[i] = {0, -i};
    rep(i, q) vec[n + i] = {v[i], -p[i]};

    // 座圧
    auto r = compression(vec);

    sort(all(vec));
    vc_unique(vec);
    int l = r.size();

    // 座圧後の値から元の値を復元
    vector<pll> rev(l);
    rep(i, l) rev[r[i]] = vec[r[i]];

    // 人iが対応する位置 (座圧後の値)
    vector<ll> pos(n);

    iota(all(pos), 0);
    // セグ木上で二分探索
    SegmentTree<int> seg(l, op, e);
    rep(i, n) seg.set(i, 1);

    rep(i, q) {
        if (v[i]) {
            // idx -> 人
            int idx = p[i];
            seg.set(pos[idx], 0);

            pos[idx] = r[n + i];
            seg.set(pos[idx], 1);

        } else {
            k = m[i];
            int idx = seg.min_left(f);
            idx--;
            cout << -rev[idx].second + 1 << " " << rev[idx].first << '\n';
        }
    }
    return 0;
}
accuracy: 0.16666666666666666
time_ms: 20
memory_kb: 9492
final_rank: 20

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

#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...)
#endif

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <class T>
using kth_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, C;
    cin >> N >> C;
    vector<ll> point(N);
    kth_set<pair<ll, int>> st;  // point * -1, id
    for (int i = 0; i < N; i++) st.insert({0, i});
    while (C--) {
        int type;
        cin >> type;
        if (type == 0) {
            int t, p;
            cin >> t >> p, t--;
            st.erase({point[t] * -1, t});
            point[t] += p;
            st.insert({point[t] * -1, t});
        }
        if (type == 1) {
            int m;
            cin >> m, m--;
            auto [p, id] = *st.find_by_order(m);
            cout << id + 1 << " " << p * -1 << '\n';
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 10368
final_rank: 3

code_snippet: #include <iostream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

typedef long long LL;

using namespace std;
using namespace __gnu_pbds;

typedef
tree<
pair<LL,LL>,
    null_type,
    greater<pair<LL,LL> >,
    rb_tree_tag,
    tree_order_statistics_node_update>map_t;

LL point[114514];

int main()
{
    map_t TREE;
    int n,c;
    cin >> n >> c;
    for(int i = 1;i <= n;++i)
        TREE.insert(make_pair(0,-i));
    for(int j = 0;j < c;++j)
    {
        int com;
        cin >> com;
        if(com == 0)
        {
            LL t,p;
            cin >> t >> p;
            TREE.erase(make_pair(point[t-1],-t));
            point[t-1]+=p;
            TREE.insert(make_pair(point[t-1],-t));
        }
        else
        {
            int m;
            cin >> m;
            --m;
            //cout << m << endl;
            cout << -TREE.find_by_order(m)->second << " " << TREE.find_by_order(m)->first << endl;
        }
    }
}
accuracy: 1
time_ms: 170
memory_kb: 10396
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
using ll = long long;


template <typename T>
struct BinaryIndexedTree {
  int N;
  vector<T> data;

  BinaryIndexedTree() = default;

  BinaryIndexedTree(int size) { init(size); }

  void init(int size) {
    N = size + 2;
    data.assign(N + 1, {});
  }

  // get sum of [0,k]
  T sum(int k) const {
    if (k < 0) return T{};  // return 0 if k < 0
    T ret{};
    for (++k; k > 0; k -= k & -k) ret += data[k];
    return ret;
  }

  // getsum of [l,r]
  inline T sum(int l, int r) const { return sum(r) - sum(l - 1); }

  // get value of k
  inline T operator[](int k) const { return sum(k) - sum(k - 1); }

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

  // range add x to [l,r]
  void imos(int l, int r, T x) {
    add(l, x);
    add(r + 1, -x);
  }

  // minimize i s.t. sum(i) >= w
  int lower_bound(T w) {
    if (w <= 0) return 0;
    int x = 0;
    for (int k = 1 << __lg(N); k; k >>= 1) {
      if (x + k <= N - 1 && data[x + k] < w) {
        w -= data[x + k];
        x += k;
      }
    }
    return x;
  }

  // minimize i s.t. sum(i) > w
  int upper_bound(T w) {
    if (w < 0) return 0;
    int x = 0;
    for (int k = 1 << __lg(N); k; k >>= 1) {
      if (x + k <= N - 1 && data[x + k] <= w) {
        w -= data[x + k];
        x += k;
      }
    }
    return x;
  }
};

int main() {
  int N, C;cin >> N >> C;
  vector<ll> T(N, 0);
  vector<pair<ll,int>> value;
  for (int i = 0;i < N;i++) value.push_back({0LL, -i});
  vector<int> OP(C);
  vector<int> SC(C);vector<ll> TH(C);
  for (int i = 0;i < C;i++) {
    cin >> OP[i];
    if (OP[i] == 1) {
      cin >> SC[i];
    } else {
      cin >> SC[i] >> TH[i];
      SC[i]--;
      T[SC[i]] += TH[i];
      value.push_back({T[SC[i]], -SC[i]});
    }
  }
  sort(value.begin(), value.end());
  value.erase(unique(value.begin(), value.end()), value.end());
  int K = value.size();
  map<pair<ll, int>, int> tos;
  for (int i = 0;i < K;i++) tos[value[i]] = i;
  for (int i = 0;i < K;i++) {
   // cout << value[i].first << " " << value[i].second << " " << i << endl;
  }
  BinaryIndexedTree<int> CNT(K+3);
  for (int i = 0;i < N;i++) CNT.add(tos[{0, -i}], 1);
  T.assign(N, 0);
  for (int i = 0;i < C;i++) {
    if (OP[i] == 0) {
      int id = SC[i];
      ll p = TH[i];
      CNT.add(tos[{T[id], -id}], -1);
      //cout << tos[{T[id], -id}] <<" B " << endl;
      T[id] += p;
      CNT.add(tos[{T[id], -id}], 1);
     // cout << tos[{T[id], -id}] << " AF " << endl;
    } else {
      int m = SC[i];
      int ok =0 ;
      int ng = K;
      while (ng-ok > 1) {
        int mid = (ok + ng) / 2;
       // cout << "MID " << mid << " " << CNT.sum(mid, K+1) << endl;
        if (CNT.sum(mid, K+1) >= m) {
          ok = mid;
        } else {
          ng = mid;
        }
      }
      int id = -value[ok].second;
      cout <<id+1<< " " << T[id] <<endl ;
    
    }
  }
  //for (int i = 0;i <= K;i++) cout << i << " " << CNT.sum(i,i) << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 22800
final_rank: 13

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

#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...)
#endif

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, C;
    cin >> N >> C;

    vector<ll> P(N);
    // {point, index * -1} を降順に管理
    tree<pair<ll, int>, null_type, greater<>, rb_tree_tag, tree_order_statistics_node_update> st;
    for (int i = 0; i < N; i++) st.insert({0, -i});

    while (C--) {
        int type;
        cin >> type;
        if (type == 0) {
            int t, p;
            cin >> t >> p, t--;
            st.erase({P[t], -t});
            P[t] += p;
            st.insert({P[t], -t});
        }
        if (type == 1) {
            int m;
            cin >> m, m--;
            auto [point, index] = *st.find_by_order(m);
            cout << -index + 1 << ' ' << point << '\n';
        }
    }
}
accuracy: 1
time_ms: 110
memory_kb: 10220
final_rank: 9

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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define int long long

template<class T>
using pbds=tree<T, null_type, greater<T>, rb_tree_tag, tree_order_statistics_node_update>;

signed main(){
	int n,q;cin>>n>>q;
	vector<int> a(n);
	pbds<pair<int,int>> tr;
	for(int i=0;i<n;i++){
		tr.insert({0,-i});
	}
	while(q--){
		int t;cin>>t;
		if(t==0){
			int i,p;cin>>i>>p;i--;
			tr.erase({a[i],-i});
			a[i]+=p;
			tr.insert({a[i],-i});
		}else{
			int m;cin>>m;m--;
			auto it=tr.find_by_order(m);
			cout<<-it->second+1<<" "<<it->first<<endl;
		}
	}
}
accuracy: 1
time_ms: 150
memory_kb: 10248
final_rank: 12

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

template<typename T,T e>
struct segtree {
	vector<T> v;
	long long n;
	function<T(T,T)> f;
	segtree(long long n,function<T(T,T)> f) : n(n), f(f) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n * 2ll;i++){
			v[i] = e;
		}
	}
	segtree(vector<T> x,function<T(T,T)> f) : n(x.size()),f(f) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n;i++){
			v[i + n] = x[i];
		}
		for(long long i = n - 1ll;i >= 0ll;i--){
			v[i] = f(v[i * 2ll],v[i * 2ll + 1ll]);
		}
	}
	T operator[](long long a){
		return v[a + n];
	}
	void set(long long a,T b){
		a += n;
		v[a] = b;
		while(a >>= 1ll){
			v[a] = f(v[a * 2ll],v[a * 2ll + 1ll]);
		}
	}
	T prod(long long l,long long r){
		T res = e;
		for(l += n,r += n;l < r;l >>= 1ll,r >>= 1ll){
			if(l & 1ll){
				res = f(res,v[l++]);
			}
			if(r & 1ll){
				res = f(res,v[--r]);
			}
		}
		return res;
	}
};
int main()
{
	long long n,c;
	cin >> n >> c;
	map<long long,set<long long>> s;
	for(long long i = 0ll;i < n;i++){
		s[0ll].insert(i);
	}
	vector<tuple<long long,long long,long long>> w(c);
	vector<long long> sc(n,0ll);
	for(long long i = 0ll;i < c;i++){
		cin >> get<0ll>(w[i]);
		if(get<0ll>(w[i]) == 0ll){
			cin >> get<1ll>(w[i]) >> get<2ll>(w[i]);
			get<1ll>(w[i])--;
			sc[get<1ll>(w[i])] += get<2ll>(w[i]);
			s[sc[get<1ll>(w[i])]].insert(get<1ll>(w[i]));
		}else{
			cin >> get<1ll>(w[i]);
		}
	}
	map<long long,map<long long,long long>> t;
	map<long long,long long> r;
	long long cou = 0ll;
	{
		for(auto itr = s.begin();itr != s.end();itr++){
			for(auto irs = itr->second.rbegin();irs != itr->second.rend();irs++){ 
				t[itr->first][*irs] = cou;
				r[cou] = *irs;
				cou++;
			}
		}
	}
	sc.assign(n,0ll);
	vector<long long> tmp(cou,0ll);
	for(long long i = 0ll;i < n;i++){
		tmp[i] = 1ll;
	}
	segtree<long long,0ll> seg(tmp,[](long long a,long long b){return a + b;});
	for(long long i = 0ll;i < c;i++){
		if(get<0ll>(w[i]) == 0ll){
			long long it = t[sc[get<1ll>(w[i])]][get<1ll>(w[i])];
			seg.set(it,0ll);
			sc[get<1ll>(w[i])] += get<2ll>(w[i]);
			it = t[sc[get<1ll>(w[i])]][get<1ll>(w[i])];
			seg.set(it,1ll);
		}else{
			long long low = 0ll,high = cou - 1ll;
			while(low < high){
				long long mid = (low + high) / 2ll;
				if(n - seg.prod(0ll,mid + 1ll) + 1ll > get<1ll>(w[i])){
					low = mid + 1ll;
				}else{
					high = mid;
				}
			}
			long long it = r[low];
			cout << it + 1ll << " " << sc[it] << endl;
		}
	}
}
accuracy: 1
time_ms: 280
memory_kb: 65688
final_rank: 16

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

template<typename T,T e>
struct segtree {
	vector<T> v;
	long long n;
	function<T(T,T)> f;
	segtree(long long n,function<T(T,T)> f) : n(n), f(f) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n * 2ll;i++){
			v[i] = e;
		}
	}
	segtree(vector<T> x,function<T(T,T)> f) : n(x.size()),f(f) {
		v.resize(n * 2ll);
		for(long long i = 0ll;i < n;i++){
			v[i + n] = x[i];
		}
		for(long long i = n - 1ll;i >= 0ll;i--){
			v[i] = f(v[i * 2ll],v[i * 2ll + 1ll]);
		}
	}
	T operator[](long long a){
		return v[a + n];
	}
	void set(long long a,T b){
		a += n;
		v[a] = b;
		while(a >>= 1ll){
			v[a] = f(v[a * 2ll],v[a * 2ll + 1ll]);
		}
	}
	T prod(long long l,long long r){
		T res = e;
		for(l += n,r += n;l < r;l >>= 1ll,r >>= 1ll){
			if(l & 1ll){
				res = f(res,v[l++]);
			}
			if(r & 1ll){
				res = f(res,v[--r]);
			}
		}
		return res;
	}
};
int main()
{
	int n,c;
	cin >> n >> c;
	map<int,set<int>> s;
	for(int i = 0;i < n;i++){
		s[0].insert(i);
	}
	vector<tuple<int,int,int>> w(c);
	vector<int> sc(n,0);
	for(int i = 0;i < c;i++){
		cin >> get<0>(w[i]);
		if(get<0>(w[i]) == 0){
			cin >> get<1>(w[i]) >> get<2>(w[i]);
			get<1>(w[i])--;
			sc[get<1>(w[i])] += get<2>(w[i]);
			s[sc[get<1>(w[i])]].insert(get<1>(w[i]));
		}else{
			cin >> get<1>(w[i]);
		}
	}
	map<int,map<int,int>> t;
	map<int,int> r;
	int cou = 0;
	{
		for(auto itr = s.begin();itr != s.end();itr++){
			for(auto irs = itr->second.rbegin();irs != itr->second.rend();irs++){ 
				t[itr->first][*irs] = cou;
				r[cou] = *irs;
				cou++;
			}
		}
	}
	sc.assign(n,0);
	vector<int> tmp(cou,0);
	for(int i = 0;i < n;i++){
		tmp[i] = 1;
	}
	segtree<int,0> seg(tmp,[](int a,int b){return a + b;});
	for(int i = 0;i < c;i++){
		if(get<0>(w[i]) == 0){
			int it = t[sc[get<1>(w[i])]][get<1>(w[i])];
			seg.set(it,0);
			sc[get<1>(w[i])] += get<2>(w[i]);
			it = t[sc[get<1>(w[i])]][get<1>(w[i])];
			seg.set(it,1);
		}else{
			int low = 0,high = cou - 1;
			while(low < high){
				int mid = (low + high) / 2;
				if(n - seg.prod(0,mid + 1) + 1 > get<1>(w[i])){
					low = mid + 1;
				}else{
					high = mid;
				}
			}
			int it = r[low];
			cout << it + 1 << " " << sc[it] << endl;
		}
	}
}
accuracy: 0.2916666666666667
time_ms: 270
memory_kb: 37268
final_rank: 18

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


#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

#if __cplusplus >= 202002L
#include <bit>
#endif

namespace atcoder {

namespace internal {

#if __cplusplus >= 202002L

using std::bit_ceil;

#else

unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

#endif

int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

#if __cplusplus >= 201703L

template <class S, auto op, auto e> struct segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");

#else

template <class S, S (*op)(S, S), S (*e)()> struct segtree {

#endif

  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder

using namespace atcoder;

int op(int x, int y){return x+y;}
int e(){return 0;}

using command = array<int, 3>;

int main() {
  int N, C;
  cin >> N >> C;
  vector<command> com(C);
  for(int i = 0; i < C; i++) {
    cin >> com[i][0];
    if(com[i][0] == 0) {
      cin >> com[i][1] >> com[i][2];
      com[i][1]--;
    }
    else {
      cin >> com[i][1];
    }
  }
  map<int, pair<long long, int>> val;
  map<pair<long long, int>, int> pos;
  {
    vector<long long> s(N);
    vector<pair<long long, int>> scores;
    for(int i = 0; i < N; i++) {
      scores.push_back(make_pair(0, i));
    }
    for(int i = 0; i < C; i++) {
      if(com[i][0] == 0) {
        int t = com[i][1];
        int p = com[i][2];
        s[t] += p;
        scores.push_back(make_pair(s[t], t));
      }
    }
    sort(scores.begin(), scores.end(), [](auto l, auto r){
      return l.first == r.first ? l.second < r.second : l.first > r.first;
    });
    for(int i = 0; i < int(scores.size()); i++) {
      val[i] = scores[i];
      pos[scores[i]] = i;
    }
  }
  int M = val.size();
  vector<long long> s(N);
  segtree<int, op, e> seg(M);
  for(int i = 0; i < N; i++) {
    seg.set(pos[make_pair(0, i)], 1);
  }
  for(int i = 0; i < C; i++) {
    if(com[i][0] == 0) {
      int t = com[i][1];
      int p = com[i][2];
      seg.set(pos[make_pair(s[t], t)], 0);
      seg.set(pos[make_pair(s[t]+p, t)], 1);
      s[t] += p;
    }
    else {
      int r = seg.max_right(0, [&](int x){return x < com[i][1];});
      cout << val[r].second+1 << " " << val[r].first << endl;
    }
  }
}
accuracy: 1
time_ms: 230
memory_kb: 34072
final_rank: 15

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

random_device seed_gen;
mt19937 engine(seed_gen());
uniform_int_distribution<int> dist_treap(0, (1 << 30) - 1);

struct S {
	ll point;
	int ind;
};

struct treap {
	struct node {
		node *lch, *rch;
		int par;
		S val;
		int cnt;
		node(S v, int p):
			lch(nullptr), rch(nullptr),
			par(p), val(v), cnt(1) {}
	};

	// a < b ?
	bool compare(S a, S b){
		if (a.point > b.point) return true;
		if (a.point < b.point) return false;
		return a.ind < b.ind;
	}

	int calc_cnt(node* t){
		if (t == nullptr) return 0;
		return t->cnt;
	}

	node* update(node* t){
		t->cnt = calc_cnt(t->lch) + calc_cnt(t->rch) + 1;
		return t;
	}

	node* merge(node* a, node* b){
		if (a == nullptr || b == nullptr){
			if (a == nullptr) return b;
			return a;
		}

		if (a->par > b->par){
			a->rch = merge(a->rch, b);
			return update(a);
		}else{
			b->lch = merge(a, b->lch);
			return update(b);
		}
	}

	pair<node*, node*> split(node* t, int k){
		if (t == nullptr) return pair(nullptr, nullptr);
		assert(0 <= k && k <= calc_cnt(t));

		if (calc_cnt(t->lch) >= k){
			pair<node*, node*> ret = split(t->lch, k);
			t->lch = ret.second;
			return pair(ret.first, update(t));
		}else{
			pair<node*, node*> ret = split(t->rch, k - calc_cnt(t->lch) - 1);
			t->rch = ret.first;
			return pair(update(t), ret.second);
		}
	}

	node* insert(node* t, int k, S v){
		return insert(t, k, v, dist_treap(engine));
	}

	node* insert(node* t, int k, S v, int p){
		pair<node*, node*> tar = split(t, k);
		node* var = new node(v, p);
		return merge(merge(tar.first, var), tar.second);
	}

	node* erase(node* t, int k){
		assert(0 <= k && k < calc_cnt(t));
		pair<node*, node*> spl1 = split(t, k + 1);
		pair<node*, node*> spl2 = split(spl1.first, k);
		delete spl2.second;
		return merge(spl2.first, spl1.second);
	}

	// returns the number of elements less than v
	int lower_bound(node* t, S v){
		if (t == nullptr) return 0;

		// if v <= t->val (i.e. all is left)
		if (!compare(t->val, v)){
			return lower_bound(t->lch, v);
		}else{
			// if v > t->val (i.e. all left is to be counted) 
			return calc_cnt(t->lch) + 1 + lower_bound(t->rch, v);
		}
	}

	node* insert(node* t, S v){
		return insert(t, lower_bound(t, v), v);
	}

	// returns val
	S get(node* t, int k){
		assert(t != nullptr);
		if (k < calc_cnt(t->lch)){
			return get(t->lch, k);
		}else if(calc_cnt(t->lch) == k){
			return t->val;
		}else{
			return get(t->rch, k - calc_cnt(t->lch) - 1);
		}
	}

	
};

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	treap T;
	treap::node* root = nullptr;
	int n, q; cin >> n >> q;
	vector<S> now(n);
	for (int i=0; i<n; i++){
		now[i] = {0, i};
		root = T.insert(root, now[i]);
	}

	while(q--){
		int t; cin >> t;
		if (t == 0){
			int i; cin >> i; i--;
			ll p; cin >> p;
			root = T.erase(root, T.lower_bound(root, now[i]));
			now[i].point += p;
			root = T.insert(root, now[i]);
		}else{
			int m; cin >> m;
			m--;
			S ret = T.get(root, m);
			cout << ret.ind + 1 << ' ' << ret.point << '\n';
		}
	}
	
}
accuracy: 1
time_ms: 90
memory_kb: 11036
final_rank: 7

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

struct Info {
    long long score = 0;
    int id = 0;
};

bool operator<(Info lhs, Info rhs) {
    if (lhs.score == rhs.score) return lhs.id < rhs.id;
    return lhs.score > rhs.score;
}

struct SegmentTree {
    std::vector<int> data;
    int n;
    int size;
    SegmentTree(int n): n(n) {
        int log = 0;
        while (n > (1 << log)) log++;
        size = 1 << log;
        data.assign(2 * size, 0);
    }
    void add(int pos, int diff) {
        assert(0 <= pos && pos < n);
        pos += size;
        data[pos] += diff;
        for (pos >>= 1; pos > 0; pos >>= 1) {
            data[pos] = data[2 * pos] + data[2 * pos + 1];
        }
    }
    int kth_element(int k) {
        int pos = 1;
        int now = 0;
        while (pos < size) {
            if (now + data[2 * pos] < k) {
                now += data[2 * pos];
                pos = 2 * pos + 1;
            } else {
                pos = 2 * pos;
            }
        }
        assert(now + data[pos] == k);
        return pos - size;
    }
};

int main() {
    int n, q;
    std::cin >> n >> q;
    std::vector<Info> cur(n);
    std::vector<Info> infos;
    for (int i = 0; i < n; i++) {
        cur[i].score = 0;
        cur[i].id = i;
        infos.push_back(cur[i]);
    }
    std::vector<std::tuple<int, int, long long>> querys;
    for (int i = 0; i < q; i++) {
        int t;
        std::cin >> t;
        if (t == 0) {
            int pos;
            long long diff;
            std::cin >> pos >> diff;
            pos--;
            querys.emplace_back(t, pos, diff);
            cur[pos].score += diff;
            infos.push_back(cur[pos]);
        } else {
            int pos;
            std::cin >> pos;
            querys.emplace_back(t, pos, -1);
        }
    }

    std::sort(infos.begin(), infos.end());
    // infos.erase(std::unique(infos.begin(), infos.end()), infos.end());
    auto compress = [&](Info info) {
        auto it = std::lower_bound(infos.begin(), infos.end(), info);
        assert(it->score == info.score);
        assert(it->id == info.id);
        return it - infos.begin();
    };
    int m = infos.size();
    SegmentTree segtree(m);
    for (int i = 0; i < n; i++) {
        cur[i].score = 0;
        cur[i].id = i;
        segtree.add(compress(cur[i]), 1);
    }

    for (auto [t, pos, diff]: querys) {
        if (t == 0) {
            segtree.add(compress(cur[pos]), -1);
            cur[pos].score += diff;
            segtree.add(compress(cur[pos]), 1);
        } else {
            int i = segtree.kth_element(pos);
            auto info = infos[i];
            std::cout << info.id + 1 << ' ' << info.score << '\n';
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 13600
final_rank: 4

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

// data-structure/splay-tree.hpp

#include <cassert>
#include <iostream>
#include <limits>
#include <memory>
#include <utility>
#include <vector>

namespace nono {

template <class Key, class T>
class SplayTree {
    struct Node;
    using NodePtr = Node*;

    struct Node {
        Node() = default;
        Node(Key key, T value): key(key), value(value), size(1), left(nullptr), right(nullptr), parent(nullptr) {}

        void right_rotate() {
            NodePtr above = parent->parent;
            NodePtr center = this;
            NodePtr below = parent;

            below->left = center->right;
            if (below->left) below->left->parent = below;

            center->right = below;
            below->parent = center;

            center->parent = above;
            if (above) {
                if (above->left == below) {
                    above->left = center;
                } else {
                    above->right = center;
                }
            }
            below->update();
            center->update();
        }

        void left_rotate() {
            NodePtr above = parent->parent;
            NodePtr center = this;
            NodePtr below = parent;

            below->right = center->left;
            if (below->right) below->right->parent = below;

            center->left = below;
            below->parent = center;

            center->parent = above;
            if (above) {
                if (above->left == below) {
                    above->left = center;
                } else {
                    above->right = center;
                }
            }
            below->update();
            center->update();
        }

        void rotate() {
            if (parent->left && parent->left == this) {
                right_rotate();
            } else {
                left_rotate();
            }
        }

        int state() {
            if (parent) {
                return (parent->left == this ? 1 : -1);
            }
            return 0;
        }

        void splay() {
            while (state() != 0) {
                if (parent->state() != 0) {
                    if (state() == parent->state()) {
                        parent->rotate();
                        rotate();
                    } else {
                        rotate();
                        rotate();
                    }
                } else {
                    rotate();
                }
            }
        }

        void update() {
            size = 1;
            if (left) size += left->size;
            if (right) size += right->size;
        }

        Key key;
        T value;
        int size;
        NodePtr left = nullptr;
        NodePtr right = nullptr;
        NodePtr parent = nullptr;
    };

  public:
    SplayTree() = default;
    SplayTree(NodePtr root): root(root) {}
    ~SplayTree() {
        destract(root);
    }

    void output() {
        output(root);
    }

    void debug() {
        debug(root);
    }

    T& get(Key key) {
        root = find(key);
        return root->value;
    }

    std::pair<Key, T> kth_element(int k) {
        root = kth_element(k, root);
        return {root->key, root->value};
    }

    void insert(Key key, T value) {
        if (!root) {
            root = new Node(key, value);
            return;
        }
        auto [lhs, rhs] = split(key);
        root = merge(merge(lhs, new Node(key, value)), rhs);
    }

    bool contains(Key key) {
        root = find(key);
        return root && root->key == key;
    }

    void erase(Key key) {
        root = find(key);
        if (root->left) root->left->parent = nullptr;
        if (root->right) root->right->parent = nullptr;
        NodePtr lhs = root->left;
        NodePtr rhs = root->right;
        root->left = nullptr;
        root->right = nullptr;
        delete root;
        root = merge(lhs, rhs);
    }


  private:
    void output(NodePtr nodeptr) {
        if (nodeptr) {
            if (nodeptr->left) output(nodeptr->left);
            std::cerr << nodeptr->key << ' ';
            if (nodeptr->right) output(nodeptr->right);
        }
    }

    void debug(NodePtr nodeptr) {
        if (!nodeptr) return;
        int size = 0;
        if (nodeptr->left) {
            size += nodeptr->left->size;
            debug(nodeptr->left);
        }
        if (nodeptr->right) {
            size += nodeptr->right->size;
            debug(nodeptr->right);
        }
    }

    static NodePtr kth_element(int k, NodePtr node) {

        if ((!node->left && k == 0) || (node->left && node->left->size == k)) {
            node->splay();
            return node;
        }
        if ((!node->left) || (node->left && node->left->size < k)) {
            if (node->right) {
                return kth_element(k - (node->left ? node->left->size : 0) - 1, node->right);
            } else {
                return nullptr;
            }
        }
        if ((!node->right) || (node->left && node->left->size > k)) {
            if (node->left) {
                return kth_element(k, node->left);
            } else {
                return nullptr;
            }
        }

        return nullptr;
    }

    std::pair<NodePtr, NodePtr> split(Key key) {
        if (!root) return {nullptr, nullptr};
        root = find(key);
        NodePtr lhs, rhs;
        if (root->key >= key) {
            lhs = root->left;
            rhs = root;
            if (lhs) lhs->parent = nullptr;
            if (rhs) rhs->left = nullptr;
        } else {
            lhs = root;
            rhs = root->right;
            if (lhs) lhs->right = nullptr;
            if (rhs) rhs->parent = nullptr;
        }
        root = nullptr;
        if (lhs) lhs->update();
        if (rhs) rhs->update();
        return {lhs, rhs};
    }

    static NodePtr merge(NodePtr lhs, NodePtr rhs) {
        if (!lhs) return rhs;
        if (!rhs) return lhs;
        NodePtr root = lhs;
        while (root->right) root = root->right;
        root->splay();
        root->right = rhs;
        rhs->parent = root;
        root->update();
        return root;
    }

    NodePtr find(Key key) {
        if (!root) return nullptr;
        NodePtr target = root;
        while (target && target->key != key) {
            if (target->key > key) {
                if (target->left) {
                    target = target->left;
                } else {
                    break;
                }
            } else {
                if (target->right) {
                    target = target->right;
                } else {
                    break;
                }
            }
        }
        target->splay();
        return target;
    }

    void destract(NodePtr node) {
        if (!node) return;
        destract(node->left);
        node->left = nullptr;
        destract(node->right);
        node->right = nullptr;
        node->parent = nullptr;
        delete node;
    }

    NodePtr root = nullptr;
};

}  //  namespace nono

namespace nono {

void solve() {
    SplayTree<std::pair<long long, int>, int> splay;
    int n, c;
    std::cin >> n >> c;
    std::vector<long long> score(n);
    for (int i = 0; i < n; i++) {
        splay.insert({0, i}, 0);
    }
    while (c--) {
        int t;
        std::cin >> t;
        if (t == 0) {
            int i;
            long long p;
            std::cin >> i >> p;
            i--;

            splay.erase({score[i], i});
            score[i] -= p;
            splay.insert({score[i], i}, 0);
        } else {
            int i;
            std::cin >> i;
            i--;
            auto [key, value] = splay.kth_element(i);
            std::cout << key.second + 1 << ' ' << -key.first << std::endl;
        }
    }
}

}  //  namespace nono

int main() {
    std::cin.tie(0)->sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(15);

    int t = 1;
    while (t--) nono::solve();
}
accuracy: 1
time_ms: 130
memory_kb: 12816
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class BIT {
public:
	int size_;
	vector<long long> dat;

	void init(int sz) {
		size_ = sz + 2;
		dat.resize(size_ + 2, 0);
	}

	void add(int pos, long long x) {
		pos += 1;
		while (pos <= size_) {
			dat[pos] += x;
			pos += (pos & -pos);
		}
	}

	long long sum(int pos) {
		long long s = 0; pos++;
		while (pos >= 1) {
			s += dat[pos];
			pos -= (pos & -pos);
		}
		return s;
	}
};

long long N;
long long Q, T[1 << 18], A[1 << 18], B[1 << 18];
long long Score[1 << 18];
vector<pair<long long, long long>> Vec;
BIT Z;

int Binary_Search(int rnk) {
	int cl = 0, cr = Vec.size() + 1, cm, minx = (1 << 30);
	for (int i = 0; i < 20; i++) {
		cm = (cl + cr) / 2;
		int val = Z.sum(cm);
		if (val >= N - rnk + 1) { cr = cm; minx = min(minx, cm); }
		else { cl = cm; }
	}
	return minx;
}

int main() {
	// Step 1. Input
	cin >> N >> Q;
	for (int i = 1; i <= Q; i++) {
		cin >> T[i];
		if (T[i] == 0) cin >> A[i] >> B[i];
		if (T[i] == 1) cin >> A[i];
	}

	// Step 2. Init Sim
	for (int i = 1; i <= N; i++) Vec.push_back(make_pair(Score[i], -i));
	for (int i = 1; i <= Q; i++) {
		if (T[i] == 1) continue;
		Score[A[i]] += B[i];
		Vec.push_back(make_pair(Score[A[i]], -A[i]));
	}
	sort(Vec.begin(), Vec.end());
	Vec.erase(unique(Vec.begin(), Vec.end()), Vec.end());
	Z.init(Vec.size() + 2);
	
	// Step 3. Simulation
	for (int i = 1; i <= N; i++) Score[i] = 0;
	for (int i = 1; i <= N; i++) Z.add(i - 1, 1);
	for (int i = 1; i <= Q; i++) {
		if (T[i] == 0) {
			int pos1 = lower_bound(Vec.begin(), Vec.end(), make_pair(Score[A[i]], -A[i])) - Vec.begin();
			Score[A[i]] += B[i];
			int pos2 = lower_bound(Vec.begin(), Vec.end(), make_pair(Score[A[i]], -A[i])) - Vec.begin();
			Z.add(pos1, -1);
			Z.add(pos2, +1);
		}
		if (T[i] == 1) {
			int pos = Binary_Search(A[i]);
			cout << -Vec[pos].second << " " << Vec[pos].first << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 15520
final_rank: 10

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0343.cc: Programming Contest II
 */

#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#include<utility>
 
using namespace std;

/* constant */

const int MAX_N = 100000;
const int BUFSIZE = MAX_N * 2;
const int INF = 1 << 30;
const long long LINF = 1LL << 62;

/* typedef */

typedef long long ll;
typedef pair<ll,int> pli;

template <typename T, const int BUFSIZE>
struct Treap {
  struct Node {
    T key, minkey;
    int fix, size;
    Node *left, *right;

    void print(int k) {
      printf("%d: key=%lld, minkey=%lld, fix=%d, size=%d\n",
	     k, key, minkey, fix, size);
    }
    void print() { print(0); }
  };
  typedef Node *node;

  node root, nullnode, buf;
  Node buf0[BUFSIZE], buf1;

  const T TINF;
  
  Treap(T tinf): TINF(tinf) {
    nullnode = &buf1;
    nullnode->left = nullnode->right = nullnode;
    nullnode->key = nullnode->minkey = TINF;
    nullnode->fix = nullnode->size = 0;
    clear();
    srand(time(NULL));
  }

  void clear() { buf = buf0; root = nullnode; }
  
  int size() { return root->size; }

  void update(node& t) {
    t->size = 1 + t->left->size + t->right->size;
    t->minkey = t->key;
    if (t->minkey > t->left->minkey) t->minkey = t->left->minkey;
    if (t->minkey > t->right->minkey) t->minkey = t->right->minkey;
  }

  node gen_node(T x) {
    node t = buf++;
    t->left = t->right = nullnode;
    t->key = t->minkey = x;
    t->fix = rand();
    t->size = 1;
    return t;
  }
  
  void rot_l(node& k1) {
    node k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void rot_r(node& k1) {
    node k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
    update(k1);
    update(k2);
    k1 = k2;
  }

  void append(node& t, T x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      append(t->right, x);
      update(t);
      if (t->right->fix > t->fix) rot_l(t);
    }
  }
  void append(T x) { append(root, x); }
  
  void insertat(node& t, int i, T x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      int lsize = t->left->size;
      if (i == lsize) {
	append(t->left, x);
	update(t);
	if (t->left->fix > t->fix) rot_r(t);
      }
      else if (i < lsize) {
	insertat(t->left, i, x);
	update(t);
	if (t->left->fix > t->fix) rot_r(t);
      }
      else {
	insertat(t->right, i - (lsize + 1), x);
	update(t);
	if (t->right->fix > t->fix) rot_l(t);
      }
    }
  }
  void insertat(int i, T x) { insertat(root, i, x); }

  void insert(node& t, T x) {
    if (t == nullnode)
      t = gen_node(x);
    else {
      if (t->key == x) return;
      if (x < t->key) {
	insert(t->left, x);
	update(t);
	if (t->left->fix > t->fix) rot_r(t);
      }
      else {
	insert(t->right, x);
	update(t);
	if (t->right->fix > t->fix) rot_l(t);
      }
    }
  }
  void insert(T x) { insert(root, x); }

  void set(node& t, int i, T x) {
    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
	t->key = t->minkey = x;
	update(t);
      }
      else if (i < lsize) {
	set(t->left, i, x);
	update(t);
      }
      else {
	set(t->right, i - (lsize + 1), x);
	update(t);
      }
    }
  }
  void set(int i, T x) { set(root, i, x); }
  
  void remove_node(node& t) {
    if (t == nullnode) return;
    if (t->left == nullnode || t->right == nullnode) {
      if (t->left == nullnode)
	t = t->right;
      else
	t = t->left;
    }
    else {
      if (t->left->fix < t->right->fix) {
	rot_l(t);
	remove_node(t->left);
	update(t);
      }
      else {
	rot_r(t);
	remove_node(t->right);
	update(t);
      }
    }
  }

  T removeat(node& t, int i) {
    T ret = TINF;

    if (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) {
	ret = t->key;
	remove_node(t);
      }
      else if (i < lsize) {
	ret = removeat(t->left, i);
	update(t);
      }
      else {
	ret = removeat(t->right, i - (lsize + 1));
	update(t);
      }
    }

    return ret;
  }
  T removeat(int i) { return removeat(root, i); }
  
  void remove(node& t, T x) {
    if (t != nullnode) {
      if (t->key == x)
	remove_node(t);
      else if (x < t->key) {
	remove(t->left, x);
	update(t);
      }
      else {
	remove(t->right, x);
	update(t);
      }
    }
  }
  void remove(T x) { remove(root, x); }
  
  int remove_range(node& t, int r0, int r1) {
    if (t == nullnode) return 0;
    if (r1 <= 0 || t->size <= r0) return 0;
    
    if (r0 <= 0 && t->size <= r1) {
      int n = t->size;
      t = nullnode;
      return n;
    }

    int lsize = t->left->size;
    int n =
      remove_range(t->left, r0, r1) +
      remove_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
    t->size = 1 + t->left->size + t->right->size;

    if (r0 <= lsize && lsize < r1) {
      n++;
      remove_node(t);
    }

    return n;
  }
  int remove_range(int r0, int r1) { return remove_range(root, r0, r1); }

  T min_range(node& t, int r0, int r1) {
    if (t == nullnode) return TINF;
    if (r1 <= 0 || t->size <= r0) return TINF;
    
    if (r0 <= 0 && t->size <= r1) return t->minkey;

    int lsize = t->left->size;
    T minval = TINF;

    if (r0 <= lsize && lsize < r1)
      minval = t->key;
    if (r0 <= lsize) {
      T minl = min_range(t->left, r0, r1);
      if (minval > minl) minval = minl;
    }
    if (lsize + 1 < r1) {
      T minr = min_range(t->right, r0 - (lsize + 1), r1 - (lsize + 1));
      if (minval > minr) minval = minr;
    }

    return minval;
  }
  T min_range(int r0, int r1) { return min_range(root, r0, r1); }

  node find(T x) {
    node t = root;
    while (t != nullnode) {
      if (t->key == x) return t;
      if (x < t->key) t = t->left;
      else t = t->right;
    }
    return (node)NULL;
  }

  T findat(int i) {
    node t = root;
    while (t != nullnode) {
      int lsize = t->left->size;
      if (i == lsize) return t->key;
      if (i < lsize)
	t = t->left;
      else {
	i -= lsize + 1;
	t = t->right;
      }
    }
    return TINF;
  }

  int upper_bound(T x) {
    node t = root;
    int k = 0;

    while (t != nullnode) {
      if (t->key <= x) {
	k += t->left->size + 1;
	t = t->right;
      }
      else {
	t = t->left;
      }
    }
    return k;
  }
};

/* global variables */

ll ss[MAX_N];
Treap<pli,BUFSIZE> trp(pli(LINF, INF));

/* subroutines */

/* main */

int main() {
  int n, qn;
  scanf("%d%d", &n, &qn);

  for (int i = 0; i < n; i++) trp.insert(pli(0, i));

  while (qn--) {
    int op;
    scanf("%d", &op);

    if (op == 0) {
      int t, p;
      scanf("%d%d", &t, &p), t--;

      trp.remove(pli(ss[t], t));
      ss[t] -= p;
      trp.insert(pli(ss[t], t));
    }
    else {
      int m;
      scanf("%d", &m), m--;

      pli v = trp.findat(m);
      printf("%d %lld\n", v.second + 1, -v.first);
    }
  }

  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 14692
final_rank: 2

code_snippet: #line 1 "/home/maspy/compro/library/my_template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define FOR4_R(i, a, b, c) for (ll i = (b)-1; i >= ll(a); i -= (c))
#define overload4(a, b, c, d, e, ...) e
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) \
  overload4(__VA_ARGS__, FOR4_R, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) for (ll t = s; t >= 0; t = (t == 0 ? -1 : (t - 1) & s))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

ll SUM(vector<int> &A) {
  ll sum = 0;
  for (auto &&a: A) sum += a;
  return sum;
}

template <typename T>
T SUM(vector<T> &A) {
  T sum = T(0);
  for (auto &&a: A) sum += a;
  return sum;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}

template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}

template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

ll binary_search(function<bool(ll)> check, ll ok, ll ng) {
  assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    if (check(x))
      ok = x;
    else
      ng = x;
  }
  return ok;
}

template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    if (check(x)) {
      ok = x;
    } else {
      ng = x;
    }
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

vi s_to_vi(const string &S, char first_char) {
  vi A(S.size());
  FOR(i, S.size()) { A[i] = S[i] - first_char; }
  return A;
}

template <typename T>
vector<T> cumsum(vector<T> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

template <typename CNT, typename T>
vc<CNT> bincount(const vc<T> &A, int size) {
  vc<CNT> C(size);
  for (auto &&x: A) { ++C[x]; }
  return C;
}

template <typename T>
vector<int> argsort(const vector<T> &A) {
  // stable
  vector<int> ids(A.size());
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return A[i] < A[j] || (A[i] == A[j] && i < j); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  int n = len(I);
  vc<T> B(n);
  FOR(i, n) B[i] = A[I[i]];
  return B;
}
#line 1 "/home/maspy/compro/library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace detail {
template <typename T, decltype(&T::is_modint) = &T::is_modint>
std::true_type check_value(int);
template <typename T>
std::false_type check_value(long);
} // namespace detail

template <typename T>
struct is_modint : decltype(detail::check_value<T>(0)) {};
template <typename T>
using is_modint_t = enable_if_t<is_modint<T>::value>;
template <typename T>
using is_not_modint_t = enable_if_t<!is_modint<T>::value>;

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <class T, is_modint_t<T> * = nullptr>
  bool read_single(T &ref) {
    long long val = 0;
    bool f = read_single(val);
    ref = T(val);
    return f;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <class A, class B, class C>
  bool read_single(tuple<A, B, C> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)));
  }
  template <class A, class B, class C, class D>
  bool read_single(tuple<A, B, C, D> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)) && read_single(get<3>(p)));
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char &val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string &s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double &x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double &x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <class T, is_modint_t<T> * = nullptr>
  void write(T &ref) {
    write(ref.val);
  }
  template <class T>
  void write(const vector<T> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> &val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <class A, class B, class C>
  void write(const tuple<A, B, C> &val) {
    auto &[a, b, c] = val;
    write(a), write(' '), write(b), write(' '), write(c);
  }
  template <class A, class B, class C, class D>
  void write(const tuple<A, B, C, D> &val) {
    auto &[a, b, c, d] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d);
  }
  template <class A, class B, class C, class D, class E>
  void write(const tuple<A, B, C, D, E> &val) {
    auto &[a, b, c, d, e] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e);
  }
  template <class A, class B, class C, class D, class E, class F>
  void write(const tuple<A, B, C, D, E, F> &val) {
    auto &[a, b, c, d, e, f] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e), write(' '), write(f);
  }
  template <class T, size_t S>
  void write(const array<T, S> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if(val < 0){
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if(negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};

Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);

void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)      \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 1 "/home/maspy/compro/library/ds/pbds.hpp"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;

// お手軽だけど、座圧＋BITとかの方がかなり速いので注意！
template <typename KEY>
using pbds_set = tree<KEY, null_type, less<KEY>, rb_tree_tag,
                      tree_order_statistics_node_update>;
#line 4 "main.cpp"

void solve() {
  LL(N, Q);
  // (score, -idx)
  pbds_set<pi> ss;
  vi A(N);
  FOR(i, N) ss.insert({A[i], -i});
  FOR(Q) {
    LL(tp);
    if (tp == 0) {
      LL(idx, p);
      --idx;
      ss.erase({A[idx], -idx});
      A[idx] += p;
      ss.insert({A[idx], -idx});
    } else {
      LL(rk);
      rk = N - rk;
      auto [a, b] = *(ss.find_by_order(rk));
      b = 1 + (-b);
      print(b, a);
    }
  }
}

signed main() {
  cout << fixed << setprecision(15);

  ll T = 1;
  // LL(T);
  FOR(T) solve();

  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 10196
final_rank: 6

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

template <typename T, int MAX_LOG, typename D = int>
struct BinaryTrie {
public:
    struct Node {
        Node *nxt[2];
        D exist;
        vector<int> accept;

        Node() : nxt{nullptr, nullptr}, exist(0) {}
    };

    Node *root;

    explicit BinaryTrie() : root(new Node()) {}

    explicit BinaryTrie(Node *root) : root(root) {}

    void add(const T &bit, D delta = 1, int idx = -1, T xor_val = 0) {
        root = add(root, bit, idx, MAX_LOG, delta, xor_val);
    }

    void erase(const T &bit, D delta = 1, T xor_val = 0) {
        add(bit, -delta, -1, xor_val);
    }

    Node *find(const T &bit, T xor_val = 0) {
        return (find(root, bit, MAX_LOG, xor_val));
    }

    D count(const T &bit, T xor_val = 0) {
        auto node = find(bit, xor_val);
        return (node ? node->exist : 0);
    }

    pair<T, Node *> min_element(T xor_val = 0) {
        assert(root->exist > 0);
        return (kth_element(0, xor_val));
    }

    pair<T, Node *> max_element(T xor_val = 0) {
        assert(root->exist > 0);
        return (kth_element(root->exist - 1, xor_val));
    }

    pair<T, Node *> kth_element(D k, T xor_val = 0) {
        assert(0 <= k && k < root->exist);
        return (kth_element(root, k, MAX_LOG, xor_val));
    }

    D count_less(const T &bit, T xor_val = 0) {
        return (count_less(root, bit, MAX_LOG, xor_val));
    }

    D size() const {
        return (root->exist);
    }

private:

    virtual Node *clone(Node *t) { return (t); }

    Node *add(Node *t, T bit, int idx, int depth, D x, T xor_val, bool need = true) {
        if (need) t = clone(t);
        if (depth == -1) {
            t->exist += x;
            if (idx >= 0) t->accept.emplace_back(idx);
        } else {
            bool f = (xor_val >> depth) & 1;
            auto &to = t->nxt[f ^ ((bit >> depth) & 1)];
            if (!to) to = new Node(), need = false;
            to = add(to, bit, idx, depth - 1, x, xor_val, need);
            t->exist += x;
        }
        return (t);
    }

    Node *find(Node *t, T bit, int depth, T xor_val) {
        if (depth == -1) {
            return (t);
        } else {
            bool f = (xor_val >> depth) & 1;
            auto &to = t->nxt[f ^ ((bit >> depth) & 1)];
            return (to ? find(to, bit, depth - 1, xor_val) : nullptr);
        }
    }

    pair<T, Node *> kth_element(Node *t, D k, int bit_index, T xor_val) {
        if (bit_index == -1) {
            return (make_pair(0, t));
        } else {
            bool f = (xor_val >> bit_index) & 1;
            if ((t->nxt[f] ? t->nxt[f]->exist : 0) <= k) {
                auto ret = kth_element(t->nxt[f ^ 1], k - (t->nxt[f] ? t->nxt[f]->exist : 0), bit_index - 1, xor_val);
                ret.first |= T(1) << bit_index;
                return (ret);
            } else {
                return (kth_element(t->nxt[f], k, bit_index - 1, xor_val));
            }
        }
    }

    D count_less(Node *t, const T &bit, int bit_index, T xor_val) {
        if (bit_index == -1) return (0);
        D ret = 0;
        bool f = (xor_val >> bit_index) & 1;
        if ((bit >> bit_index & 1) && t->nxt[f]) ret += t->nxt[f]->exist;
        if (t->nxt[f ^ (bit >> bit_index & 1)]) ret += count_less(t->nxt[f ^ (bit >> bit_index & 1)], bit, bit_index - 1, xor_val);
        return (ret);
    }
};

int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, c;
    cin >> n >> c;

    vector<long long> score(n + 1);
    BinaryTrie<__uint128_t, 63> bt;

    for (int i = 1; i <= n; ++i) bt.add(n - i);

    for (int i = 0; i < c; ++i) {
        int com;
        cin >> com;
        if (com == 0) {
            int t, p;
            cin >> t >> p;

            bt.erase(score[t] * n + (n - t));
            score[t] += p;
            bt.add(score[t] * n + (n - t));
        } else {
            int m;
            cin >> m;

            auto res = bt.kth_element(n - m).first;

            cout << (int) (n - res % n) << ' ' << (long long) (res / n) << '\n';
        }
    }

    return (0);
}
accuracy: 1
time_ms: 190
memory_kb: 132168
final_rank: 17

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

template <typename T, int MAX_LOG, typename D = int>
struct BinaryTrie {
public:
    struct Node {
        Node *nxt[2];
        D exist;
        vector<int> accept;

        Node() : nxt{nullptr, nullptr}, exist(0) {}
    };

    Node *root;

    explicit BinaryTrie() : root(new Node()) {}

    explicit BinaryTrie(Node *root) : root(root) {}

    void add(const T &bit, D delta = 1, int idx = -1, T xor_val = 0) {
        root = add(root, bit, idx, MAX_LOG, delta, xor_val);
    }

    void erase(const T &bit, D delta = 1, T xor_val = 0) {
        add(bit, -delta, -1, xor_val);
    }

    Node *find(const T &bit, T xor_val = 0) {
        return (find(root, bit, MAX_LOG, xor_val));
    }

    D count(const T &bit, T xor_val = 0) {
        auto node = find(bit, xor_val);
        return (node ? node->exist : 0);
    }

    pair<T, Node *> min_element(T xor_val = 0) {
        assert(root->exist > 0);
        return (kth_element(0, xor_val));
    }

    pair<T, Node *> max_element(T xor_val = 0) {
        assert(root->exist > 0);
        return (kth_element(root->exist - 1, xor_val));
    }

    pair<T, Node *> kth_element(D k, T xor_val = 0) {
        assert(0 <= k && k < root->exist);
        return (kth_element(root, k, MAX_LOG, xor_val));
    }

    D count_less(const T &bit, T xor_val = 0) {
        return (count_less(root, bit, MAX_LOG, xor_val));
    }

    D size() const {
        return (root->exist);
    }

private:

    virtual Node *clone(Node *t) { return (t); }

    Node *add(Node *t, T bit, int idx, int depth, D x, T xor_val, bool need = true) {
        if (need) t = clone(t);
        if (depth == -1) {
            t->exist += x;
            if (idx >= 0) t->accept.emplace_back(idx);
        } else {
            bool f = (xor_val >> depth) & 1;
            auto &to = t->nxt[f ^ ((bit >> depth) & 1)];
            if (!to) to = new Node(), need = false;
            to = add(to, bit, idx, depth - 1, x, xor_val, need);
            t->exist += x;
        }
        return (t);
    }

    Node *find(Node *t, T bit, int depth, T xor_val) {
        if (depth == -1) {
            return (t);
        } else {
            bool f = (xor_val >> depth) & 1;
            auto &to = t->nxt[f ^ ((bit >> depth) & 1)];
            return (to ? find(to, bit, depth - 1, xor_val) : nullptr);
        }
    }

    pair<T, Node *> kth_element(Node *t, D k, int bit_index, T xor_val) {
        if (bit_index == -1) {
            return (make_pair(0, t));
        } else {
            bool f = (xor_val >> bit_index) & 1;
            if ((t->nxt[f] ? t->nxt[f]->exist : 0) <= k) {
                auto ret = kth_element(t->nxt[f ^ 1], k - (t->nxt[f] ? t->nxt[f]->exist : 0), bit_index - 1, xor_val);
                ret.first |= T(1) << bit_index;
                return (ret);
            } else {
                return (kth_element(t->nxt[f], k, bit_index - 1, xor_val));
            }
        }
    }

    D count_less(Node *t, const T &bit, int bit_index, T xor_val) {
        if (bit_index == -1) return (0);
        D ret = 0;
        bool f = (xor_val >> bit_index) & 1;
        if ((bit >> bit_index & 1) && t->nxt[f]) ret += t->nxt[f]->exist;
        if (t->nxt[f ^ (bit >> bit_index & 1)]) ret += count_less(t->nxt[f ^ (bit >> bit_index & 1)], bit, bit_index - 1, xor_val);
        return (ret);
    }
};

int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, c;
    cin >> n >> c;

    vector<int64_t> score(n + 1);
    BinaryTrie<__uint128_t, 64> bt;

    for (int i = 1; i <= n; ++i) bt.add(n - i);

    for (int i = 0; i < c; ++i) {
        int com;
        cin >> com;
        if (com == 0) {
            int t, p;
            cin >> t >> p;

            bt.erase(score[t] * n + (n - t));
            score[t] += p;
            bt.add(score[t] * n + (n - t));
        } else {
            int m;
            cin >> m;

            auto res = bt.kth_element(n - m).first;

            cout << (long long) (n - res % n) << ' ' << (int) (res / n) << '\n';
        }
    }

    return (0);
}
accuracy: 0.2916666666666667
time_ms: 180
memory_kb: 117700
final_rank: 19