Problem:
I - The J-th Number
Problem Statement
You are given
N
empty arrays,
t_1, ..., t_n
. At first, you execute
M
queries as follows.
add a value
v
to array
t_i
(
a \leq i \leq b
)
Next, you process
Q
following output queries.
output the
j
-th number of the sequence sorted all values in
t_i
(
x \leq i \leq y
)
Input
The dataset is formatted as follows.
N
M
Q
a_1
b_1
v_1
...
a_M
b_M
v_M
x_1
y_1
j_1
...
x_Q
y_Q
j_Q
The first line contains three integers
N
(
1 \leq N \leq 10^9
),
M
(
1 \leq M \leq 10^5
) and
Q
(
1 \leq Q \leq 10^5
). Each of the following
M
lines consists of three integers
a_i
,
b_i
and
v_i
(
1 \leq a_i \leq b_i \leq N
,
1 \leq v_i \leq 10^9
). Finally the following
Q
lines give the list of output queries, each of these lines consists of three integers
x_i
,
y_i
and
j_i
(
1 \leq x_i \leq y_i \leq N, 1 \leq j_i \leq Σ_{x_i \leq k \leq y_i} |t_k|
).
Output
For each output query, print in a line the
j
-th number.
Sample Input 1
5 4 1
1 5 1
1 1 3
4 5 1
3 4 2
1 3 4
Output for the Sample Input 1
2
After the
M
-th query is executed, each
t_i
is as follows:
[1,3], [1], [1,2], [1,1,2], [1,1]
The sequence sorted values in
t_1
,
t_2
and
t_3
is [1,1,1,2,3]. In the sequence, the 4-th number is 2.
Sample Input 2
10 4 4
1 4 11
2 3 22
6 9 33
8 9 44
1 1 1
4 5 1
4 6 2
1 10 12
Output for the Sample Input 2
11
11
33
44

Submitted solutions:

code_snippet: #ifdef NACHIA
#define _GLIBCXX_DEBUG
#else
#define NDEBUG
#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i,n) for(ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template <class A, class B> void chmax(A& l, const B& r){ if(l < r) l = r; }
template <class A, class B> void chmin(A& l, const B& r){ if(r < l) l = r; }

struct Elem { ll a, b; };
Elem operator+(Elem l, Elem r){ return { l.a + r.a, l.b + r.b }; }

struct Node {
  Node *l, *r;
  Elem sum;
};
using np = Node*;

Node pool[10000000];
np poolptr = pool;
np alloc(){
  return poolptr++;
}
np newleaf(Elem v){
  auto res = alloc();
  res->l = 0; res->r = 0;
  res->sum = v;
  return res;
}
np newmid(np l, np r){
  auto res = alloc();
  res->l = l; res->r = r;
  res->sum = l->sum + r->sum;
  return res;
}
np upd(np x, ll p, Elem v, ll a, ll b){
  if(a + 1 == b) return newleaf(v);
  ll m = (a + b) / 2;
  if(p < m) return newmid(upd(x->l, p, v, a, m), x->r);
  return newmid(x->l, upd(x->r, p, v, m, b));
}
np init(ll n){
  if(n == 1) return newleaf({0,0});
  return newmid(init(n/2), init(n-n/2));
}

void testcase(){
  ll N, M, Q; cin >> N >> M >> Q;
  V<ll> A(M), B(M), C(M);
  REP(i,M){ cin >> A[i] >> B[i] >> C[i]; A[i]--; }
  V<tuple<ll,ll,ll>> queries(M*2);
  REP(i,M) queries[i] = { A[i], i, 0 };
  REP(i,M) queries[i+M] = { B[i], i, 1 };
  sort(queries.begin(), queries.end());
  V<ll> timing;
  for(auto [t,u,v] : queries) timing.push_back(t);

  V<ll> I(M), O(M);
  REP(i,M) I[i] = i;
  sort(I.begin(), I.end(), [&](ll l, ll r){ return C[l] < C[r]; });
  REP(i,M) O[I[i]] = i;

  V<np> ds(queries.size() + 1);
  ds[0] = init(M);

  REP(i,queries.size()){
    auto [t,u,v] = queries[i];
    if(v == 0){
      ds[i+1] = upd(ds[i], O[u], {1,-t}, 0, M);
    } else {
      ds[i+1] = upd(ds[i], O[u], {0,B[u]-A[u]}, 0, M);
    }
  }

  REP(qi,Q){
    ll x, y, j; cin >> x >> y >> j; x--;
    ll fx = lower_bound(timing.begin(), timing.end(), x) - timing.begin();
    ll fy = lower_bound(timing.begin(), timing.end(), y) - timing.begin();
    ll a = 0, b = M;
    np vx = ds[fx], vy = ds[fy];
    while(a + 1 < b){
      ll m = (a + b) / 2;
      ll cnt = (vy->l->sum.a * y + vy->l->sum.b) - (vx->l->sum.a * x + vx->l->sum.b);
      if(cnt < j){ j -= cnt; vx = vx->r; vy = vy->r; a = m; }
      else{ vx = vx->l; vy = vy->l; b = m; }
    }
    cout << C[I[a]] << "\n";
  }
}

int main(){
  cin.tie(0)->sync_with_stdio(0);
  testcase();
  return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 133920
final_rank: 11

code_snippet: #ifdef t9unkubj
#include"debug.cpp"
//#include"template_no_debug.h"
#else 
#define dbg(...) 199958
#endif

#undef _GLIBCXX_DEBUG
#pragma GCC optimize("O3")
using namespace std;
#include<bits/stdc++.h>
using ll=long long;
using ull=unsigned long long;
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++)
#define DREP(i,n,m) for(ll i=(n);i>=(m);i--)
#define drep(i,n) for(ll i=((n)-1);i>=0;i--)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
template<class T,class F>
bool chmin(T &x, F y){
    if(x>y){
        x=y;
        return true;
    }
    return false;
}
template<class T, class F>
bool chmax(T &x, F y){
    if(x<y){
        x=y;
        return true;
    }
    return false;
}
double pass_time=0;

template <class T,T (*op)(T, T),class F,T (*mapping)(T,F),F (*merge)(F, F)>
struct lazy_segtree{
    int n;
    vector<T>data;
    vector<F>lazy;
    int log;
    T e;
    F id;
    lazy_segtree(int n1,T e,F id):n(n1),e(e),id(id){
        int n_=1;
        log=0;
        while(n_<=n)n_*=2,log++;
        data=vector<T>(n_*2,e);
        lazy=vector<F>(n_,id);
        n=n_;
        for(int i=n_-1;i>0;i--)update(i);
    }
    void update(int k){
        data[k]=op(data[k*2],data[k*2+1]);
    }
    void apply(int k,F x){//
        data[k]=mapping(data[k],x);
        if(k<n){
            lazy[k]=merge(lazy[k],x);
            if(lazy[k]==id)return;
            //segment tree beats! if(data[k].fail)push(k),update(k);
        }
    }
    void push(int k){//上から遅延素を伝播させる
        apply(k*2,lazy[k]);
        apply(k*2+1,lazy[k]);
        lazy[k]=id;
    }
    void set(int p,T x){
        p+=n;
        for(int i=log;i>=1;i--){
            push(p>>i);
        }
        data[p]=x;
        for(int i=1;i<=log;i++){
            update(p>>i);
        }
    }
    void apply(int l,int r,F x){
        if(l==r)return;
        l+=n,r+=n;
        for(int i=log;i>=1;i--){
            if(((l>>i)<<i)!=l)push(l>>i);
            if(((r>>i)<<i)!=r)push((r-1)>>i);
        } 
        int l2{l},r2{r};
        while(l<r){
            if(l&1)apply(l++,x);
            if(r&1)apply(--r,x);
            l>>=1,r>>=1;
        }
        l=l2,r=r2;
        for(int i=1;i<=log;i++){
            if(((l>>i)<<i)!=l)update(l>>i);
            if(((r>>i)<<i)!=r)update((r-1)>>i);
        }
    }
    T prod(int l,int r){
        l+=n,r+=n;
        for(int i=log;i>=1;i--){
            if(((l>>i)<<i)!=l)push(l>>i);
            if(((r>>i)<<i)!=r)push((r-1)>>i);
        } 
        T sml=e,smr=e;
        while(l<r){
            if(l&1)sml=op(sml,data[l++]);
            if(r&1)smr=op(data[--r],smr);
            l>>=1,r>>=1;
        }
        return op(sml,smr);
    }
    T get(int p){
        p+=n;
        for(int i=log;i>=1;i--)push(p>>i);
        return data[p];
    }
};
/*
並列二分探索
区間add区間sum
*/
struct S{
    ll val;
    ll sz;
};
S op(S a,S b){
    return {a.val+b.val,a.sz+b.sz};
}
S MAP(S a,ll b){
    a.val+=b*a.sz;
    return a;
}
ll MERGE(ll a,ll b){
    return a+b;
}
void solve(){
    ll n,m,q;
    cin>>n>>m>>q;
    vc<ll>a(m),b(m),v(m);
    rep(i,m)cin>>a[i]>>b[i]>>v[i],a[i]--;
    //答えがac以下である⇔ac以下のものがj個以上存在する
    vc<ll>ac(q,1e9+100),wa(q),wj(q);
    vc<ll>x(q),y(q),j(q);
    rep(i,q)cin>>x[i]>>y[i]>>j[i],x[i]--;
    vc<ll>toa(m),tob(m),tox(q),toy(q);
    vc<ll>l,r;
    
    ll M;
    {
        map<ll,ll>compress;
        rep(i,m)compress[a[i]]=compress[b[i]]=0;
        rep(i,q)compress[x[i]]=compress[y[i]]=0;
        compress[0]=compress[n]=0;
        int id=0;
        for(auto&[x,y]:compress)y=id++;
        rep(i,m)toa[i]=compress[a[i]];
        rep(i,m)tob[i]=compress[b[i]];
        rep(i,q)tox[i]=compress[x[i]];
        rep(i,q)toy[i]=compress[y[i]];
        M=compress.size()-1;
        l.resize(M);
        r.resize(M);
        for(auto&[x,y]:compress){
            if(y<M)l[y]=x;
            if(y)r[y-1]=x;
        }
    }
    dbg(l,r);
    vc<array<ll,3>>query;
    query.reserve(q+m);
    rep(t,32){
        lazy_segtree<S,op,ll,MAP,MERGE>seg(M,{},0);
        rep(i,M)seg.set(i,{0,r[i]-l[i]});
        rep(i,q){
            wj[i]=ac[i]+wa[i]>>1;
            if(ac[i]-wa[i]>1)query.push_back(array<ll,3>{wj[i],0,(int)i});
        }
        rep(i,m){
            query.push_back({v[i],-1,(int)i});
        }
        sort(all(query));
        for(auto&[vl,type,i]:query){
            if(type==0){
                if(seg.prod(tox[i],toy[i]).val>=j[i]){
                    ac[i]=wj[i];
                }else wa[i]=wj[i];
            }else{
                seg.apply(toa[i],tob[i],1);
            }
        }
        query.clear();
        query.reserve(q+m);
    }
    rep(i,q)cout<<ac[i]<<"\n";
}
signed main(){
#ifdef t9unkubj
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
    cin.tie(0)->sync_with_stdio(0);
    pass_time=clock();
    int t=1;
    //cin>>t;
    while(t--)solve();
    pass_time=clock()-pass_time;
    dbg(pass_time/CLOCKS_PER_SEC);
}
accuracy: 1
time_ms: 3810
memory_kb: 60852
final_rank: 12

code_snippet: #ifdef t9unkubj
#include"debug.cpp"
//#include"template_no_debug.h"
#else 
#define dbg(...) 199958
#endif

#undef _GLIBCXX_DEBUG
#pragma GCC optimize("O3")
using namespace std;
#include<bits/stdc++.h>
using ll=long long;
using ull=unsigned long long;
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++)
#define DREP(i,n,m) for(ll i=(n);i>=(m);i--)
#define drep(i,n) for(ll i=((n)-1);i>=0;i--)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
template<class T,class F>
bool chmin(T &x, F y){
    if(x>y){
        x=y;
        return true;
    }
    return false;
}
template<class T, class F>
bool chmax(T &x, F y){
    if(x<y){
        x=y;
        return true;
    }
    return false;
}
double pass_time=0;

template <class T,T (*op)(T, T),class F,T (*mapping)(T,F),F (*merge)(F, F)>
struct lazy_segtree{
    int n;
    vector<T>data;
    vector<F>lazy;
    int log;
    T e;
    F id;
    lazy_segtree(int n1,T e,F id):n(n1),e(e),id(id){
        int n_=1;
        log=0;
        while(n_<=n)n_*=2,log++;
        data=vector<T>(n_*2,e);
        lazy=vector<F>(n_,id);
        n=n_;
        for(int i=n_-1;i>0;i--)update(i);
    }
    void update(int k){
        data[k]=op(data[k*2],data[k*2+1]);
    }
    void apply(int k,F x){//
        data[k]=mapping(data[k],x);
        if(k<n){
            lazy[k]=merge(lazy[k],x);
            if(lazy[k]==id)return;
            //segment tree beats! if(data[k].fail)push(k),update(k);
        }
    }
    void push(int k){//上から遅延素を伝播させる
        apply(k*2,lazy[k]);
        apply(k*2+1,lazy[k]);
        lazy[k]=id;
    }
    void set(int p,T x){
        p+=n;
        for(int i=log;i>=1;i--){
            push(p>>i);
        }
        data[p]=x;
        for(int i=1;i<=log;i++){
            update(p>>i);
        }
    }
    void apply(int l,int r,F x){
        if(l==r)return;
        l+=n,r+=n;
        for(int i=log;i>=1;i--){
            if(((l>>i)<<i)!=l)push(l>>i);
            if(((r>>i)<<i)!=r)push((r-1)>>i);
        } 
        int l2{l},r2{r};
        while(l<r){
            if(l&1)apply(l++,x);
            if(r&1)apply(--r,x);
            l>>=1,r>>=1;
        }
        l=l2,r=r2;
        for(int i=1;i<=log;i++){
            if(((l>>i)<<i)!=l)update(l>>i);
            if(((r>>i)<<i)!=r)update((r-1)>>i);
        }
    }
    T prod(int l,int r){
        l+=n,r+=n;
        for(int i=log;i>=1;i--){
            if(((l>>i)<<i)!=l)push(l>>i);
            if(((r>>i)<<i)!=r)push((r-1)>>i);
        } 
        T sml=e,smr=e;
        while(l<r){
            if(l&1)sml=op(sml,data[l++]);
            if(r&1)smr=op(data[--r],smr);
            l>>=1,r>>=1;
        }
        return op(sml,smr);
    }
    T get(int p){
        p+=n;
        for(int i=log;i>=1;i--)push(p>>i);
        return data[p];
    }
};
/*
並列二分探索
区間add区間sum
*/
struct S{
    ll val;
    ll sz;
};
S op(S a,S b){
    return {a.val+b.val,a.sz+b.sz};
}
S MAP(S a,ll b){
    a.val+=b*a.sz;
    return a;
}
ll MERGE(ll a,ll b){
    return a+b;
}
void solve(){
    int n,m,q;
    cin>>n>>m>>q;
    vc<int>a(m),b(m),v(m);
    rep(i,m)cin>>a[i]>>b[i]>>v[i],a[i]--;
    //答えがac以下である⇔ac以下のものがj個以上存在する
    vc<int>ac(q,1e9),wa(q),wj(q);
    vc<int>x(q),y(q),j(q);
    rep(i,q)cin>>x[i]>>y[i]>>j[i],x[i]--;
    vc<int>toa(m),tob(m),tox(q),toy(q);
    vc<int>l,r;
    
    int M;
    {
        map<int,int>compress;
        rep(i,m)compress[a[i]]=compress[b[i]]=0;
        rep(i,q)compress[x[i]]=compress[y[i]]=0;
        compress[0]=compress[n]=0;
        int id=0;
        for(auto&[x,y]:compress)y=id++;
        rep(i,m)toa[i]=compress[a[i]];
        rep(i,m)tob[i]=compress[b[i]];
        rep(i,q)tox[i]=compress[x[i]];
        rep(i,q)toy[i]=compress[y[i]];
        M=compress.size()-1;
        l.resize(M);
        r.resize(M);
        for(auto&[x,y]:compress){
            if(y<M)l[y]=x;
            if(y)r[y-1]=x;
        }
    }
    vc<array<int,3>>query;
    query.reserve(q+m);
    rep(t,32){
        lazy_segtree<S,op,ll,MAP,MERGE>seg(M,{},0);
        rep(i,M)seg.set(i,{0,r[i]-l[i]});
        rep(i,q){
            wj[i]=ac[i]+wa[i]>>1;
            if(ac[i]-wa[i]>1)query.push_back(array<int,3>{wj[i],0,(int)i});
        }
        rep(i,m){
            query.push_back({v[i],-1,(int)i});
        }
        sort(all(query));
        for(auto&[vl,type,i]:query){
            if(type==0){
                if(seg.prod(tox[i],toy[i]).val>=j[i]){
                    ac[i]=wj[i];
                }else wa[i]=wj[i];
            }else{
                seg.apply(toa[i],tob[i],1);
            }
        }
        query.clear();
        query.reserve(q+m);
    }
    rep(i,q)cout<<ac[i]<<"\n";
}
signed main(){
#ifdef t9unkubj
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
    cin.tie(0)->sync_with_stdio(0);
    pass_time=clock();
    int t=1;
    //cin>>t;
    while(t--)solve();
    pass_time=clock()-pass_time;
    dbg(pass_time/CLOCKS_PER_SEC);
}
accuracy: 0.696969696969697
time_ms: 950
memory_kb: 15396
final_rank: 20

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <cassert>
#include <random>
#include <utility>

struct FenwickTree {
    int n;
    std::vector<long long> f;
    FenwickTree(int N) : n{N}, f(n + 1) {}
    void add(int i, long long x) {
        assert(0 <= i and i < n);
        for ( i++ ; i <= n ; i += i & -i) f[i] += x;
    }
    long long pref(int r) const {
        assert(0 <= r and r <= n);
        long long res{};
        for ( ; r ; r -= r & -r) res += f[r];
        return res;
    }
    long long prod(int l, int r) const {
        return -pref(l) + pref(r);
    }
};

int N, M, Q;
int A[100010], B[100010], V[100010], X[100010], Y[100010];
long long J[100010];
std::vector<int> x_values;

std::vector<long long> solver(const std::vector<std::pair<int, int>>& yi) {
    std::vector<std::vector<std::pair<int, bool>>> add(x_values.size()), sum(x_values.size());
    for (int i{} ; i < M ; i++) {
        add[A[i]].emplace_back(V[i], false);
        add[B[i]].emplace_back(V[i], true);
    }
    for (int i{} ; i < (int)yi.size() ; i++) {
        int j{yi[i].second};
        sum[X[j]].emplace_back(i, true);
        sum[Y[j]].emplace_back(i, false);
    }
    FenwickTree f1(M), f2(M);
    std::vector<long long> res(yi.size());
    for (int x{} ; x < (int)x_values.size() ; x++) {
        // std::cout << std::endl << "start " << x << std::endl;
        // kiyo: (r - l)v = rv - lv
        for (auto [idx, s] : sum[x]) {
            long long sign{s ? -1LL : 1LL};
            int y{yi[idx].first + 1};
            long long kiyo{(long long)x_values[x] * f1.pref(y) - f2.pref(y)};
            // std::cout << f1.pref(y) << ' ' << f2.pref(y) << ' ' << kiyo << std::endl;
            res[idx] += sign * kiyo;
        }
        for (auto [y, s] : add[x]) {
            long long sign{s ? -1LL : 1LL};
            // std::cout << "add " << y << ' ' << sign << std::endl;
            f1.add(y, sign);
            f2.add(y, (long long)x_values[x] * sign);
        }
    }
    // for (unsigned i{} ; i < yi.size() ; i++) {
    //     std::cout << yi[i].first << ' ' << ',' << yi[i].second << ',' << ' ' << res[i] << std::endl;
    // }
    // std::cout << "-----------------\n";
    return res;
}

// std::mt19937 mt{std::random_device{}()};

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    // while (true) {
    //     {
    //         N = mt() % 100 + 1;
    //         M = mt() % 100 + 1;
    //         Q = 100;
    //         std::cout << N << ' ' << M << ' ' << Q << std::endl;
    //     }
    std::cin >> N >> M >> Q;
    // std::vector<std::vector<int>> all(N);
    for (int i{} ; i < M ; i++) {
        // {
        //     A[i] = mt() % N + 1;
        //     B[i] = mt() % N + 1;
        //     if (A[i] > B[i]) std::swap(A[i], B[i]);
        //     V[i] = mt() % 100 + 1;
        //     std::cout << A[i] << ' ' << B[i] << ' ' << V[i] << std::endl;
        //     A[i]--;
        //     for (int j{A[i]} ; j < B[i] ; j++) all[j].push_back(V[i]);
        // }
        std::cin >> A[i] >> B[i] >> V[i];
        A[i]--;
        x_values.push_back(A[i]);
        x_values.push_back(B[i]);
        // {
        //     for (int j{A[i]} ; j < B[i] ; j++) all[j].push_back(V[i]);
        // }
    }
    std::vector<int> comp(V, V + M);
    {
        std::sort(comp.begin(), comp.end());
        comp.erase(std::unique(comp.begin(), comp.end()), comp.end());
        for (int i{} ; i < M ; i++) 
            V[i] = int(std::lower_bound(comp.begin(), comp.end(), V[i]) - comp.begin());
    }
    for (int i{} ; i < Q ; i++) {
        // {
        //     while (true) {
        //         X[i] = mt() % N + 1;
        //         Y[i] = mt() % N + 1;
        //         if (X[i] > Y[i]) std::swap(X[i], Y[i]);
        //         X[i]--;
        //         int sum{};
        //         for (int j{X[i]} ; j < Y[i] ; j++) sum += (int)all[j].size();
        //         if (sum) {
        //             J[i] = mt() % sum + 1;
        //             break;
        //         }
        //     }
        //     std::cout << X[i] + 1 << ' ' << Y[i] << ' ' << J[i] << std::endl;
        // }
        std::cin >> X[i] >> Y[i] >> J[i];
        X[i]--;
        x_values.push_back(X[i]);
        x_values.push_back(Y[i]);
    }
    std::sort(x_values.begin(), x_values.end());
    x_values.erase(std::unique(x_values.begin(), x_values.end()), x_values.end());
    for (int i{} ; i < M ; i++) {
        A[i] = int(std::lower_bound(x_values.begin(), x_values.end(), A[i]) - x_values.begin());
        B[i] = int(std::lower_bound(x_values.begin(), x_values.end(), B[i]) - x_values.begin());
    }
    for (int i{} ; i < Q ; i++) {
        X[i] = int(std::lower_bound(x_values.begin(), x_values.end(), X[i]) - x_values.begin());
        Y[i] = int(std::lower_bound(x_values.begin(), x_values.end(), Y[i]) - x_values.begin());
    }
    std::vector<int> ok(Q, -1), ng(Q, (int)comp.size() - 1);
    while (true) {
        std::vector<std::pair<int, int>> mid;
        mid.reserve(Q);
        for (int i{} ; i < Q ; i++) if (ng[i] - ok[i] > 1) {
            mid.push_back(std::pair{ (ok[i] + ng[i]) / 2, i });
        }
        if (mid.empty()) break;
        auto cnt{solver(mid)};
        assert(cnt.size() == mid.size());
        for (int i{} ; i < (int)cnt.size() ; i++) {
            int idx{mid[i].second};
            if (cnt[i] < J[idx]) ok[idx] = mid[i].first;
            else ng[idx] = mid[i].first;
        }
        // for (int i{} ; i < Q ; i++) {
        //     std::cout << '(' << ok[i] << ',' << ng[i] << ')' << ' ';
        // }
        // std::cout << std::endl;
    }
    for (int i{} ; i < Q ; i++) {
        int ans{comp[ng[i]]};
        // {
        //     int brute{};
        //     std::vector<int> cur;
        //     for (int j{X[i]} ; j < Y[i] ; j++) for (auto x : all[j]) cur.push_back(x);
        //     std::sort(cur.begin(), cur.end());
        //     if (ans != cur[J[i] - 1]) {
        //         std::cout << "fail! " << ans << ' ' << "but " << cur[J[i] - 1] << std::endl;
        //         std::exit(0);
        //     }
        // }
        std::cout << ans << '\n';
    }
    // std::cout << "--------------------------" << std::endl;
    // // break;
    // }
}
accuracy: 1
time_ms: 1230
memory_kb: 42980
final_rank: 2

code_snippet: // #pragma GCC target("avx2")
#pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<sys/time.h>

#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,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_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()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as F(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "compostiion must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {

#endif

  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_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());
        lz = std::vector<F>(size, id());
        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;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        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() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder


using namespace std;

// using mint = atcoder::modint1000000007;


using P = pair<int, int>;


const int M = 998244353;
const long long LM = 1LL << 60;


struct S {
    long long s, w;
    S() {}
    S(long long s, long long w) : s(s), w(w) {}
};

using F = long long;

S op(const S& l, const S& r) {
    return S(l.s + r.s, l.w + r.w);
}
S e() {
    return S(0, 0);
}
S mapping(const F& f, const S& s) {
    return S(s.s + f * s.w, s.w);
}
F composition(const F& a, const F& b) {
    return a + b;
}
F id() {
    return 0;
}



int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    int n, m, q;
    cin >> n >> m >> q;
    vector<pair<long long, P>> ops(m);
    set<int> se;
    for (int i = 0; i < m; ++i) {
        int l, r;
        long long v;
        cin >> l >> r >> v;
        --l;
        ops[i] = { v, { l, r } };
        se.insert(l);
        se.insert(r);
    }
    sort(ops.begin(), ops.end());
    vector<pair<P, long long>> queries(q);
    for (int i = 0; i < q; ++i) {
        int l, r;
        long long k;
        cin >> l >> r >> k;
        --l;
        queries[i] = { { l, r }, k };
        se.insert(l);
        se.insert(r);
    }
    n = (int)se.size() - 1;
    unordered_map<int, int> mp;
    vector<int> ps(n + 1), w(n);
    {
        int j = 0;
        for (auto& i : se) {
            ps[j] = i;
            mp[i] = j;
            ++j;
        }
    }
    for (int i = 0; i < n; ++i) {
        w[i] = ps[i + 1] - ps[i];
    }
    for (auto& i : ops) {
        i.second.first = mp[i.second.first];
        i.second.second = mp[i.second.second];
    }
    for (auto& i : queries) {
        i.first.first = mp[i.first.first];
        i.first.second = mp[i.first.second];
    }

    vector<int> ngs(q, -1), oks(q, m - 1);
    while (true) {
        int c = 0;
        vector<vector<int>> qs(m);
        for (int i = 0; i < q; ++i) {
            if (ngs[i] + 1 < oks[i]) {
                int mid = (ngs[i] + oks[i]) / 2;
                qs[mid].push_back(i);
                ++c;
            }
        }
        if (c == 0) {
            break;
        }
        vector<S> ini(n);
        for (int i = 0; i < n; ++i) {
            ini[i] = S(0, w[i]);
        }
        atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> sg(ini);
        for (int i = 0; i < m; ++i) {
            {
                int l = ops[i].second.first;
                int r = ops[i].second.second;
                sg.apply(l, r, 1);
            }
            for (auto& j : qs[i]) {
                int l = queries[j].first.first;
                int r = queries[j].first.second;
                long long k = queries[j].second;
                if (sg.prod(l, r).s >= k) {
                    oks[j] = i;
                }
                else {
                    ngs[j] = i;
                }
            }
        }
    }
    for (auto& i : oks) {
        cout << ops[i].first << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 1360
memory_kb: 74952
final_rank: 8

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

// =================================================================== Binary Indexed Tree ===================================================================
class BIT {
public:
	int size_ = 1;
	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 += 1;
		while (pos >= 1) {
			s += dat[pos];
			pos -= (pos & -pos);
		}
		return s;
	}
};

class BIT2 {
public:
	vector<long long> Zahyou;
	BIT L1;
	BIT L0;

	void init(vector<long long> Z) {
		Zahyou = Z;
		L1.init(Zahyou.size() + 2);
		L0.init(Zahyou.size() + 2);
	}

	void add(int l, int r, long long x) {
		L1.add(l, +x); L0.add(l, -x * (Zahyou[l] - 1));
		L1.add(r, -x); L0.add(r, +x * (Zahyou[r] - 1));
	}
	
	long long sum(int pos) {
		long long val1 = L1.sum(pos);
		long long val2 = L0.sum(pos);
		return 1LL * Zahyou[pos] * val1 + val2;
	}
};

// =================================================================== Main Part ===================================================================
long long N;
long long M, A[100009], B[100009], V[100009];
long long Q, X[100009], Y[100009], J[100009], Answer[100009];
vector<long long> List;

void Execute(vector<pair<int, int>> Order) {
	BIT2 Z;Z.init(List);
	int cur = 0;

	// Execute Start
	for (int i = 0; i < Order.size(); i++) {
		int cst = Order[i].first;
		int idx = Order[i].second;
		while (cur < M && V[cur] <= cst) {
			Z.add(A[cur], B[cur], 1);
			cur += 1;
		}
		long long cnts = Z.sum(Y[idx]) - Z.sum(X[idx]);
		if (cnts < J[idx]) Answer[idx] = cst;
	}
}

int main() {
	// Step 1. Input
	cin >> N >> M >> Q;
	for (int i = 0; i < M; i++) cin >> A[i] >> B[i] >> V[i];
	for (int i = 0; i < Q; i++) cin >> X[i] >> Y[i] >> J[i];

	// Step 2. Adjust
	vector<tuple<long long, long long, long long>> Vec;
	for (int i = 0; i < M; i++) Vec.push_back(make_tuple(V[i], A[i], B[i]));
	sort(Vec.begin(), Vec.end());
	for (int i = 0; i < M; i++) {
		V[i] = get<0>(Vec[i]);
		A[i] = get<1>(Vec[i]);
		B[i] = get<2>(Vec[i]);
	}

	// Step 3. Compression
	for (int i = 0; i < M; i++) List.push_back(A[i]);
	for (int i = 0; i < M; i++) List.push_back(B[i] + 1);
	for (int i = 0; i < Q; i++) List.push_back(X[i] - 1);
	for (int i = 0; i < Q; i++) List.push_back(Y[i]);
	sort(List.begin(), List.end());
	List.erase(unique(List.begin(), List.end()), List.end());
	for (int i = 0; i < M; i++) A[i] = lower_bound(List.begin(), List.end(), A[i]) - List.begin();
	for (int i = 0; i < M; i++) B[i] = lower_bound(List.begin(), List.end(), B[i] + 1) - List.begin();
	for (int i = 0; i < Q; i++) X[i] = lower_bound(List.begin(), List.end(), X[i] - 1) - List.begin();
	for (int i = 0; i < Q; i++) Y[i] = lower_bound(List.begin(), List.end(), Y[i]) - List.begin();

	// Step 4. Parallel Binary Search
	for (int i = 29; i >= 0; i--) {
		vector<pair<int, int>> Order;
		for (int j = 0; j < Q; j++) Order.push_back(make_pair(Answer[j] + (1 << i), j));
		sort(Order.begin(), Order.end());
		Execute(Order);
	}

	// Step 5. Output
	for (int i = 0; i < Q; i++) cout << Answer[i] + 1 << endl;
	return 0;
}
accuracy: 1
time_ms: 1150
memory_kb: 28680
final_rank: 1

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

using ll = long long;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

template<typename ...Ts>
decltype(auto) zip(vector<Ts>... args){
  vector<decltype(make_tuple(args[0]...))> res;
  int n=min({args.size()...});
  res.reserve(n);
  for(int i=0;i<n;i++) res.emplace_back(args[i]...);
  return res;
}

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F &&init, G &&apply,CHK &&check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int n, m, q;
    cin >> n >> m >> q;

    vector<int> a {0,1000000007};
    vector<array<int ,3>> op1(m);
    vector<array<int ,2>> op2(q);
    vector<long long> qs(q);
    
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op1[i][j];
        }
        op1[i][0]--;
        a.push_back(op1[i][0]);
        a.push_back(op1[i][1]);
    }

    sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    	return x[2] < y[2];
    });

    for (int i = 0; i < q; ++i) {
        cin >> op2[i][0] >> op2[i][1] >> qs[i];
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for (int i = 0; i < m; ++i) {
		op1[i][0] = v(op1[i][0]);
		op1[i][1] = v(op1[i][1]);
	}
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(op1[i][0], op1[i][1], 1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= qs[i];
	};

	auto ans=paral_bs(q, m, init, apply, chk);
	
	for(int i = 0; i < q; i++) 
		cout << op1[ans[i]][2] << '\n';

    return 0;
}
accuracy: 1
time_ms: 1690
memory_kb: 48808
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

using ll = long long;

template<typename ...Ts>
decltype(auto) zip(vector<Ts>... args){
  vector<decltype(make_tuple(args[0]...))> res;
  int n=min({args.size()...});
  res.reserve(n);
  for(int i=0;i<n;i++) res.emplace_back(args[i]...);
  return res;
}

template<typename V>
V compress(V vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  return vs;
}

template<typename T>
map<T, int> dict(const vector<T> &vs){
  map<T, int> res;
  for(int i=0;i<(int)vs.size();i++)
    res[vs[i]]=i;
  return res;
}
map<char, int> dict(const string &s){
  return dict(vector<char>(s.begin(),s.end()));
}
template<typename T>
vector<T> compressed(vector<T> vs){
  auto dc=dict(compress(vs));
  for(auto &v:vs) v=dc[v];
  return vs;
}

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};
/*
using P = pair<ll, int>;
auto f=[&](P a,P b){return P(a.first+b.first,a.second+b.second);};
auto g=[&](P a,int b){return P(a.first+(ll)b*a.second,a.second);};
auto h=[&](int a,int b){return a+b;};
SegmentTree<P, int> seg(f,g,h,P(0,0),0);
*/
using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }
// 


void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

vector<int> parallel_binary_search(int n,int q,
                                   function<void(void)> init,
                                   function<void(int)> apply,
                                   function<bool(int)> check){
  vector< vector<int> > C(q);
  vector<int> L(n,-1),R(n,q);
  bool flg=1;
  while(flg){
    flg=0;
    init();
    for(int i=0;i<n;i++)
      if(L[i]+1<R[i]) C[(L[i]+R[i])>>1].emplace_back(i);
    for(int i=0;i<q;i++){
      flg|=!C[i].empty();
      apply(i);
      for(int j:C[i]){
        if(check(j)) R[j]=i;
        else L[j]=i;
      }
      C[i].clear();
    }
  }
  return R;
}

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};


int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<int> a{0,1000000007};
    vector<int> as(m), bs(m), vs(m);
    for (int i = 0; i < m; ++i) {
        cin >> as[i] >> bs[i] >> vs[i];
        as[i]--;
        a.push_back(as[i]);
        a.push_back(bs[i]);
    }

    auto vt=zip(vs,as,bs);

 
    sort(vt.begin(),vt.end());
    for(int i=0;i<m;i++) 
    	tie(vs[i],as[i],bs[i])=vt[i];


    vector<int> xs(q),ys(q);
    vector<ll> js(q);
    for(int i=0;i<q;i++){
        cin>>xs[i]>>ys[i]>>js[i],xs[i]--;
        a.push_back(xs[i]);
        a.push_back(ys[i]);
    }

    Discrete<int> v(a);
    const auto &ps=v.xs;
	// auto dc=dict(ps);


	vector<S> vp(ps.size()-1);
	for(int i=0;i+1<(int)ps.size();i++) vp[i]=S(0,ps[i+1]-ps[i]);
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for(int &a:as) a=v(a);
	for(int &b:bs) b=v(b);
	for(int &x:xs) x=v(x);
	for(int &y:ys) y=v(y);

	auto init=[&](){
	// seg.build(vp);
		for(int i=0;i<vp.size();++i){
			seg.set(i,vp[i]);
		}
	};
	auto apply=[&](int i){
		seg.apply(as[i],bs[i],1);
	// seg.update(as[i],bs[i],1);
	};
	auto check=[&](int i){
	return seg.get(xs[i],ys[i]).first>=js[i];
	};


	auto ans=parallel_binary_search(q,m,init,apply,check);
	
	// wt(ans);wt(vs);

	for(int i=0;i<q;i++) cout<<vs[ans[i]]<<"\n";

    return 0;
}
accuracy: 1
time_ms: 1730
memory_kb: 49800
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

using ll = long long;

template<typename ...Ts>
decltype(auto) zip(vector<Ts>... args){
  vector<decltype(make_tuple(args[0]...))> res;
  int n=min({args.size()...});
  res.reserve(n);
  for(int i=0;i<n;i++) res.emplace_back(args[i]...);
  return res;
}

template<typename T, typename ...Ts>
vector<T> fusion(vector<T> bs,Ts... ts){
  auto append=[&](auto vs){for(auto v:vs) bs.emplace_back(v);};
  initializer_list<int>{(void(append(ts)),0)...};
  return bs;
}

template<typename V>
V compress(V vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  return vs;
}

template<typename T>
map<T, int> dict(const vector<T> &vs){
  map<T, int> res;
  for(int i=0;i<(int)vs.size();i++)
    res[vs[i]]=i;
  return res;
}
map<char, int> dict(const string &s){
  return dict(vector<char>(s.begin(),s.end()));
}
template<typename T>
vector<T> compressed(vector<T> vs){
  auto dc=dict(compress(vs));
  for(auto &v:vs) v=dc[v];
  return vs;
}

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};
/*
using P = pair<ll, int>;
auto f=[&](P a,P b){return P(a.first+b.first,a.second+b.second);};
auto g=[&](P a,int b){return P(a.first+(ll)b*a.second,a.second);};
auto h=[&](int a,int b){return a+b;};
SegmentTree<P, int> seg(f,g,h,P(0,0),0);
*/
using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }
// 


void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

vector<int> parallel_binary_search(int n,int q,
                                   function<void(void)> init,
                                   function<void(int)> apply,
                                   function<bool(int)> check){
  vector< vector<int> > C(q);
  vector<int> L(n,-1),R(n,q);
  bool flg=1;
  while(flg){
    flg=0;
    init();
    for(int i=0;i<n;i++)
      if(L[i]+1<R[i]) C[(L[i]+R[i])>>1].emplace_back(i);
    for(int i=0;i<q;i++){
      flg|=!C[i].empty();
      apply(i);
      for(int j:C[i]){
        if(check(j)) R[j]=i;
        else L[j]=i;
      }
      C[i].clear();
    }
  }
  return R;
}

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};


int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<int> a{0,1000000007};
    vector<int> as(m), bs(m), vs(m);
    for (int i = 0; i < m; ++i) {
        cin >> as[i] >> bs[i] >> vs[i];
        as[i]--;
        a.push_back(as[i]);
        a.push_back(bs[i]);
    }

    auto vt=zip(vs,as,bs);

 
    sort(vt.begin(),vt.end());
    for(int i=0;i<m;i++) 
    	tie(vs[i],as[i],bs[i])=vt[i];


    vector<int> xs(q),ys(q);
    vector<ll> js(q);
    for(int i=0;i<q;i++){
        cin>>xs[i]>>ys[i]>>js[i],xs[i]--;
        a.push_back(xs[i]);
        a.push_back(ys[i]);
    }

    Discrete<int> v(a);
    const auto &ps=v.xs;
	auto dc=dict(ps);


	vector<S> vp(ps.size()-1);
	for(int i=0;i+1<(int)ps.size();i++) vp[i]=S(0,ps[i+1]-ps[i]);
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for(int &a:as) a=dc[a];
	for(int &b:bs) b=dc[b];
	for(int &x:xs) x=dc[x];
	for(int &y:ys) y=dc[y];

	auto init=[&](){
	// seg.build(vp);
		for(int i=0;i<vp.size();++i){
			seg.set(i,vp[i]);
		}
	};
	auto apply=[&](int i){
		seg.apply(as[i],bs[i],1);
	// seg.update(as[i],bs[i],1);
	};
	auto check=[&](int i){
	return seg.get(xs[i],ys[i]).first>=js[i];
	};


	auto ans=parallel_binary_search(q,m,init,apply,check);
	
	// wt(ans);wt(vs);

	for(int i=0;i<q;i++) cout<<vs[ans[i]]<<"\n";

    return 0;
}
accuracy: 1
time_ms: 1910
memory_kb: 68444
final_rank: 10

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

using ll = long long;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

template<typename ...Ts>
decltype(auto) zip(vector<Ts>... args){
  vector<decltype(make_tuple(args[0]...))> res;
  int n=min({args.size()...});
  res.reserve(n);
  for(int i=0;i<n;i++) res.emplace_back(args[i]...);
  return res;
}

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F &&init, G &&apply,CHK &&check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

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

    // freopen("/Users/yangyf/Downloads/in.txt", "r", stdin);
    // freopen("/Users/yangyf/Desktop/out1.txt", "w", stdout);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<int> a {0,1000000007};

    vector<int> as(m), bs(m), vs(m);
    for (int i = 0; i < m; ++i) {
        cin >> as[i] >> bs[i] >> vs[i];
        as[i]--;
        a.push_back(as[i]);
        a.push_back(bs[i]);
    }

    auto vt=zip(vs,as,bs);

    sort(vt.begin(),vt.end());
    for(int i=0;i<m;i++) 
    	tie(vs[i],as[i],bs[i])=vt[i];

    vector<vector<int>> op1(m, vector<int>(3)), op2(q, vector<int>(3));
    
    // for (int i = 0; i < m; ++i) {
    //     for (int j = 0; j < 3; ++j) {
    //     	cin >> op1[i][j];
    //     }
    //     op1[i][0]--;
    //     a.push_back(op1[i][0]);
    //     a.push_back(op1[i][1]);
    // }

    // sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    // 	return make_tuple(x[2], x[0], x[1]) < make_tuple(y[2], y[0], y[1]);
    // });

    for (int i = 0; i < q; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op2[i][j];
        }
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	// for (int i = 0; i < m; ++i) {
	// 	op1[i][0] = v(op1[i][0]);
	// 	op1[i][1] = v(op1[i][1]);
	// }
	for(int &x:as) x=v(x);
	for(int &x:bs) x=v(x);
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(as[i], bs[i], 1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= op2[i][2];
	};

	auto ans=paral_bs(q, m, init, apply, chk);
	
	for(int i = 0; i < q; i++) 
		cout << vs[ans[i]] << '\n';

    return 0;
}
accuracy: 0.696969696969697
time_ms: 440
memory_kb: 20252
final_rank: 19

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

using ll = long long;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F& init, G &apply,CHK &check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

vector<int> parallel_binary_search(int n,int q,
                                   function<void(void)> init,
                                   function<void(int)> apply,
                                   function<bool(int)> check){
  vector< vector<int> > C(q);
  vector<int> L(n,-1),R(n,q);
  bool flg=1;
  while(flg){
    flg=0;
    init();
    for(int i=0;i<n;i++)
      if(L[i]+1<R[i]) C[(L[i]+R[i])>>1].emplace_back(i);
    for(int i=0;i<q;i++){
      flg|=!C[i].empty();
      apply(i);
      for(int j:C[i]){
        if(check(j)) R[j]=i;
        else L[j]=i;
      }
      C[i].clear();
    }
  }
  return R;
}

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

    // freopen("/Users/yangyf/Downloads/in.txt", "r", stdin);
    // freopen("/Users/yangyf/Desktop/out1.txt", "w", stdout);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<vector<int>> op1(m, vector<int>(3)), op2(q, vector<int>(3));
    vector<int> a {0,1000000007};
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op1[i][j];
        }
        op1[i][0]--;
        a.push_back(op1[i][0]);
        a.push_back(op1[i][1]);
    }

    sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    	return make_tuple(x[2], x[0], x[1]) < make_tuple(y[2], y[0], y[1]);
    });

    for (int i = 0; i < q; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op2[i][j];
        }
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for (int i = 0; i < m; ++i) {
		op1[i][0] = v(op1[i][0]);
		op1[i][1] = v(op1[i][1]);
	}
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(op1[i][0], op1[i][1], 1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= op2[i][2];
	};

	auto ans=parallel_binary_search(q, m, init, apply, chk);
	
	for(int i = 0; i < q; i++) 
		cout << op1[ans[i]][2] << '\n';

    return 0;
}
accuracy: 0.696969696969697
time_ms: 460
memory_kb: 18920
final_rank: 18

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

using ll = long long;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2563

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F& init, G &apply,CHK &check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<vector<int>> op1(m, vector<int>(3)), op2(q, vector<int>(3));
    vector<int> a {0,1000000007};
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op1[i][j];
        }
        op1[i][0]--;
        a.push_back(op1[i][0]);
        a.push_back(op1[i][1]);
    }

    sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    	return make_tuple(x[2], x[0], x[1]) < make_tuple(y[2], y[0], y[1]);
    });

    for (int i = 0; i < q; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op2[i][j];
        }
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for (int i = 0; i < m; ++i) {
		op1[i][0] = v(op1[i][0]);
		op1[i][1] = v(op1[i][1]);
	}
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(op1[i][0], op1[i][1], 1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= op2[i][2];
	};

	auto ans=paral_bs(q, m, init, apply, chk);
	
	for(int i = 0; i < q; i++) 
		cout << op1[ans[i]][2] << '\n';

    return 0;
}
accuracy: 0.696969696969697
time_ms: 440
memory_kb: 18780
final_rank: 15

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

using ll = long long;

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F&& init, G &&apply,CHK &&check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<vector<int>> op1(m, vector<int>(3)), op2(q, vector<int>(3));
    vector<int> a {0,1000000007};
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op1[i][j];
        }
        op1[i][0]--;
        a.push_back(op1[i][0]);
        a.push_back(op1[i][1]);
    }

    sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    	return make_tuple(x[2], x[0], x[1]) < make_tuple(y[2], y[0], y[1]);
    });

    for (int i = 0; i < q; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op2[i][j];
        }
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for (int i = 0; i < m; ++i) {
		op1[i][0] = v(op1[i][0]);
		op1[i][1] = v(op1[i][1]);
	}
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(op1[i][0], op1[i][1],1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= op2[i][2];
	};

	auto ans=paral_bs(q, m, init, apply, chk);
	
	for(int i = 0;i < q; i++) 
		cout << op1[ans[i]][2] << '\n';

    return 0;
}
accuracy: 0.696969696969697
time_ms: 460
memory_kb: 18804
final_rank: 17

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

using ll = long long;

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};

using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }

template <class T>
struct Discrete {
    vector<T> xs;
    Discrete(const vector<T>& v) {
        xs = v;
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
    }
    int get(const T& x) const {
        return lower_bound(xs.begin(), xs.end(), x) - xs.begin();
    }
    inline int operator()(const T& x) const { return get(x); }
    T operator[](int i) { return xs[i]; }
    int size() const { return xs.size(); }
};

template<typename F, typename G, typename CHK> 
vector<int> paral_bs(int n, int q, F&& init, G &&apply,CHK &&check){
    vector<vector<int>> a(q);
    vector<int> l(n, -1), r(n, q);
    bool ok = 1;
    while (ok) {
    	ok = 0;
    	init();
    	for (int i = 0; i < n; ++i) if (l[i] + 1 < r[i])
    		a[(l[i] + r[i]) >> 1].push_back(i);
    	for (int i = 0; i < q; ++i) {
    		ok |= !a[i].empty();
    		apply(i);
    		for (int j : a[i]) {
    			if (check(j)) r[j] = i;
    			else l[j] = i;
    		}
    		a[i].clear();
    	}
    }
    return r;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;

    vector<vector<int>> op1(m, vector<int>(3)), op2(q, vector<int>(3));
    vector<int> a {0,1000000007};
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op1[i][j];
        }
        op1[i][0]--;
        a.push_back(op1[i][0]);
        a.push_back(op1[i][1]);
    }

    sort(op1.begin(), op1.end(), [&](auto &x, auto &y){
    	return x[2] < y[2];
    });

    for (int i = 0; i < q; ++i) {
        for (int j = 0; j < 3; ++j) {
        	cin >> op2[i][j];
        }
        op2[i][0]--;
        a.push_back(op2[i][0]);
        a.push_back(op2[i][1]);
    }

    Discrete<int> v(a);
    
	vector<S> vp(v.size() - 1);
	for (int i = 0; i < v.size() - 1; ++i) {
		vp[i] = S{0, v[i + 1] - v[i]};
	}
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for (int i = 0; i < m; ++i) {
		op1[i][0] = v(op1[i][0]);
		op1[i][1] = v(op1[i][1]);
	}
	for (int i = 0; i < q; ++i) {
		op2[i][0] = v(op2[i][0]);
		op2[i][1] = v(op2[i][1]);
	}

	auto init = [&](){
		for(int i = 0;i < vp.size(); ++i){
			seg.set(i, vp[i]);
		}
	};
	auto apply = [&](int i){
		seg.apply(op1[i][0], op1[i][1],1);
	};
	auto chk = [&](int i){
		return seg.get(op2[i][0], op2[i][1]).first >= op2[i][2];
	};

	auto ans=paral_bs(q, m, init, apply, chk);
	
	for(int i = 0;i < q; i++) 
		cout << op1[ans[i]][2] << '\n';

    return 0;
}
accuracy: 0.696969696969697
time_ms: 450
memory_kb: 18916
final_rank: 16

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

using ll = long long;

template<typename ...Ts>
decltype(auto) zip(vector<Ts>... args){
  vector<decltype(make_tuple(args[0]...))> res;
  int n=min({args.size()...});
  res.reserve(n);
  for(int i=0;i<n;i++) res.emplace_back(args[i]...);
  return res;
}

template<typename T, typename ...Ts>
vector<T> fusion(vector<T> bs,Ts... ts){
  auto append=[&](auto vs){for(auto v:vs) bs.emplace_back(v);};
  initializer_list<int>{(void(append(ts)),0)...};
  return bs;
}

template<typename V>
V compress(V vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  return vs;
}

template<typename T>
map<T, int> dict(const vector<T> &vs){
  map<T, int> res;
  for(int i=0;i<(int)vs.size();i++)
    res[vs[i]]=i;
  return res;
}
map<char, int> dict(const string &s){
  return dict(vector<char>(s.begin(),s.end()));
}
template<typename T>
vector<T> compressed(vector<T> vs){
  auto dc=dict(compress(vs));
  for(auto &v:vs) v=dc[v];
  return vs;
}

// template <typename T,typename E>
// struct SegmentTree{
//   using F = function<T(T,T)>;
//   using G = function<T(T,E)>;
//   using H = function<E(E,E)>;
//   int n,height;
//   F f;
//   G g;
//   H h;
//   T ti;
//   E ei;
//   vector<T> dat;
//   vector<E> laz;
//   SegmentTree(F f,G g,H h,T ti,E ei):
//     f(f),g(g),h(h),ti(ti),ei(ei){}

//   void init(int n_){
//     n=1;height=0;
//     while(n<n_) n<<=1,height++;
//     dat.assign(2*n,ti);
//     laz.assign(2*n,ei);
//   }

//   void build(const vector<T> &v){
//     int n_=v.size();
//     init(n_);
//     for(int i=0;i<n_;i++) dat[n+i]=v[i];
//     for(int i=n-1;i;i--)
//       dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
//   }

//   inline T reflect(int k){
//     return laz[k]==ei?dat[k]:g(dat[k],laz[k]);
//   }

//   inline void propagate(int k){
//     if(laz[k]==ei) return;
//     laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
//     laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
//     dat[k]=reflect(k);
//     laz[k]=ei;
//   }

//   inline void thrust(int k){
//     for(int i=height;i;i--) propagate(k>>i);
//   }

//   inline void recalc(int k){
//     while(k>>=1)
//       dat[k]=f(reflect((k<<1)|0),reflect((k<<1)|1));
//   }

//   void update(int a,int b,E x){
//     if(a>=b) return;
//     thrust(a+=n);
//     thrust(b+=n-1);
//     for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
//       if(l&1) laz[l]=h(laz[l],x),l++;
//       if(r&1) --r,laz[r]=h(laz[r],x);
//     }
//     recalc(a);
//     recalc(b);
//   }

//   void set_val(int a,T x){
//     thrust(a+=n);
//     dat[a]=x;laz[a]=ei;
//     recalc(a);
//   }

//   T query(int a,int b){
//     if(a>=b) return ti;
//     thrust(a+=n);
//     thrust(b+=n-1);
//     T vl=ti,vr=ti;
//     for(int l=a,r=b+1;l<r;l>>=1,r>>=1) {
//       if(l&1) vl=f(vl,reflect(l++));
//       if(r&1) vr=f(reflect(--r),vr);
//     }
//     return f(vl,vr);
//   }

//   template<typename C>
//   int find(int st,C &check,T &acc,int k,int l,int r){
//     if(l+1==r){
//       acc=f(acc,reflect(k));
//       return check(acc)?k-n:-1;
//     }
//     propagate(k);
//     int m=(l+r)>>1;
//     if(m<=st) return find(st,check,acc,(k<<1)|1,m,r);
//     if(st<=l and !check(f(acc,dat[k]))){
//       acc=f(acc,dat[k]);
//       return -1;
//     }
//     int vl=find(st,check,acc,(k<<1)|0,l,m);
//     if(~vl) return vl;
//     return find(st,check,acc,(k<<1)|1,m,r);
//   }

//   template<typename C>
//   int find(int st,C &check){
//     T acc=ti;
//     return find(st,check,acc,1,0,n);
//   }
// };

template <class S,           // 线段树维护的数据信息
          S (*op)(S, S),    // 左右子节点信息合并到当前节点
          S (*e)(),
          class F,          // 懒标记维护的信息
          S (*tag)(F, S),  // 查询时给当去节点打上懒标记
          F (*merge)(F, F),  // 懒标记合并
          F (*id)()>        // 懒标记的默认值, 用于清空父节点的懒标记
struct LazySegTree {
    int n, size, log;
    vector<S> d;
    vector<F> lz;
    void pull(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void push_down(int k, F f) {
        d[k] = tag(f, d[k]);
        if (k < size) lz[k] = merge(f, lz[k]);
    }
    void push(int k) {
        push_down(2 * k, lz[k]), push_down(2 * k + 1, lz[k]);
        lz[k] = id();
    }
    LazySegTree() : LazySegTree(0) {}
    explicit LazySegTree(int N) : LazySegTree(vector<S>(N, e())) {}
    explicit LazySegTree(const vector<S>& v) : n(int(v.size())) {
        log = ceil_lg(n), size = 1 << log;
        d = vector<S>(2 * size, e()), lz = vector<F>(size, id());
        for (int i = 0; i < n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) pull(i);
    }
    int ceil_lg(int x) {   // minimum non-neg x s.t. `n <= 2^x`
        return x <= 1 ? 0 : 32 - __builtin_clz(x - 1);
    }
    void set(int p, S x) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    S get(int p) {     // Assert 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }
    S get(int l, int r) {   // op(a[l], ..., a[r - 1])
        if (l == r) return e();
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        S sl = e(), sr = e();
        while (l < r) {
            if (l & 1) sl = op(sl, d[l++]);
            if (r & 1) sr = op(d[--r], sr);
            l >>= 1, r >>= 1;
        }
        return op(sl, sr);
    }
    S get_all() { return d[1]; }
    void apply(int p, F f) {   // 0 <= p < n
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = tag(f, d[p]);
        for (int i = 1; i <= log; i++) pull(p >> i);
    }
    void apply(int l, int r, F f) {  // a[i] = f(a[i]), [l, r)
        if (l == r) return;
        l += size, r += size;
        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }
        int l2 = l, r2 = r;
        while (l < r) {
            if (l & 1) push_down(l++, f);
            if (r & 1) push_down(--r, f);
            l >>= 1, r >>= 1;
        }
        l = l2, r = r2;
        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) pull(l >> i);
            if (((r >> i) << i) != r) pull((r - 1) >> i);
        }
    }
    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) { // 0 <= l <= n, g(e()) is true
        if (l == n) return n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) { // 0 <= r <= n, g(e()) is true
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    }
};
/*
using P = pair<ll, int>;
auto f=[&](P a,P b){return P(a.first+b.first,a.second+b.second);};
auto g=[&](P a,int b){return P(a.first+(ll)b*a.second,a.second);};
auto h=[&](int a,int b){return a+b;};
SegmentTree<P, int> seg(f,g,h,P(0,0),0);
*/
using S = pair<ll, int>;
using F = long long;
S op(S x, S y) {
    S s;
    s = S{x.first+y.first,x.second+y.second};
    return s;
}
S e() {
    return S();
};
S tag(F f, S s) { return S{s.first + f * s.second, s.second}; }
F merge(F x, F y) { return x + y; }
F id() { return 0; }
// 


void wt(vector<int> &v){
	for(auto&x:v)cout<<x<<' ';cout<<'\n';
}

vector<int> parallel_binary_search(int n,int q,
                                   function<void(void)> init,
                                   function<void(int)> apply,
                                   function<bool(int)> check){
  vector< vector<int> > C(q);
  vector<int> L(n,-1),R(n,q);
  bool flg=1;
  while(flg){
    flg=0;
    init();
    for(int i=0;i<n;i++)
      if(L[i]+1<R[i]) C[(L[i]+R[i])>>1].emplace_back(i);
    for(int i=0;i<q;i++){
      flg|=!C[i].empty();
      apply(i);
      for(int j:C[i]){
        if(check(j)) R[j]=i;
        else L[j]=i;
      }
      C[i].clear();
    }
  }
  return R;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    
    int n, m, q;
    cin >> n >> m >> q;
    vector<int> as(m), bs(m), vs(m);
    for (int i = 0; i < m; ++i) {
        cin >> as[i] >> bs[i] >> vs[i];
        as[i]--;
    }

    auto vt=zip(vs,as,bs);

 
    sort(vt.begin(),vt.end());
    for(int i=0;i<m;i++) 
    	tie(vs[i],as[i],bs[i])=vt[i];

    // for(int i=0;i<m;++i){
    // 	cout<<as[i] << ' ' << bs[i] << ' ' << vs[i] << '\n';
    // }

    vector<int> xs(q),ys(q);
    vector<ll> js(q);
    for(int i=0;i<q;i++)
    	cin>>xs[i]>>ys[i]>>js[i],xs[i]--;
    auto ps=compress(fusion(as,bs,xs,ys,vector<int>({0,1000000007})));
	auto dc=dict(ps);

	

	vector<S> vp(ps.size()-1);
	for(int i=0;i+1<(int)ps.size();i++) vp[i]=S(0,ps[i+1]-ps[i]);
	LazySegTree<S, op, e, F, tag, merge, id> seg(vp.size());

	for(int &a:as) a=dc[a];
	for(int &b:bs) b=dc[b];
	for(int &x:xs) x=dc[x];
	for(int &y:ys) y=dc[y];

	auto init=[&](){
	// seg.build(vp);
		for(int i=0;i<vp.size();++i){
			seg.set(i,vp[i]);
		}
	};
	auto apply=[&](int i){
		seg.apply(as[i],bs[i],1);
	// seg.update(as[i],bs[i],1);
	};
	auto check=[&](int i){
	return seg.get(xs[i],ys[i]).first>=js[i];
	};


	auto ans=parallel_binary_search(q,m,init,apply,check);
	
	// wt(ans);wt(vs);

	for(int i=0;i<q;i++) cout<<vs[ans[i]]<<"\n";

    return 0;
}
accuracy: 1
time_ms: 1910
memory_kb: 66940
final_rank: 9

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

#define rep(i, n) for(int i = 0; i < int(n); i++)
#define per(i, n) for(int i = (n) - 1; 0 <= i; i--)
#define rep2(i, l, r) for(int i = (l); i < int(r); i++)
#define per2(i, l, r) for(int i = (r) -1; int(l) <= i; i--)
#define MM << " " <<
#define pb push_back
#define eb emplace_back
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define sz(x) int(x.size())
#define each(e, x) for(auto &x : x)

template<class T>
void print(const vector<T> &v, T x = 0) {
    int n = sz(v);
    for(int i = 0; i < n; i++) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if(v.empty()) cout << '\n';
}

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

template<class T>
bool chmax(T &x, const T &y) {
    return (x < y) ? (x = y, true) : false;
}

template<class T>
bool chmin(T &x, const T &y) {
    return (x > y) ? (x = y, true) : false;
}

struct io_setup {
        io_setup() {
            ios_base::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << fixed << setprecision(15);
        }
    } io_set;

template<class T, class O, class F, class G, class H>
struct LazySeg {
    vector<T> dat;
    vector<O> laz;
    int n;
    const F f;
    const G g;
    const H h;
    const T e1;
    const O e2;

    LazySeg(vector<T> v, F f, G g, H h, T e1, O e2)
    : f(f), g(g), h(h), e1(e1), e2(e2) {
        int m = v.size();
        n = 1;
        while (n < m) n *= 2;
        dat.assign(2 * n, e1);
        rep(i, m) dat[n + i] = v[i];
        laz.assign(2 * n, e2);
        per2(i, 1, n) dat[i] = f(dat[i * 2], dat[2 * i + 1]);
    }

    T get(int k) { return g(dat[k], laz[k]); }

    void eval(int k) {
        dat[k] = get(k);
        rep(i, 2) laz[2 * k + i] = h(laz[2 * k + i], laz[k]);
        laz[k] = e2;
    }

    T apply(int l, int r, O x, int k = 1, int L = 0, int R = -1) {
        if(R == -1) R = n;
        if(l >= r || r <= L || R <= l) return get(k);
        if(l <= L && R <= r) {
            laz[k] = h(laz[k], x);
            return get(k);
        }
        eval(k);
        int M = (L + R) / 2;
        return dat[k] = f(apply(l, r, x, 2 * k, L, M),
                          apply(l, r, x, 2 * k + 1, M, R));
    }

    T query(int l, int r, int k = 1, int L = 0, int R = -1) {
        if (R == -1) R = n;
        if(l >= r || r <= L || R <= l) return e1;
        if(l <= L && R <= r) return get(k);
        eval(k);
        int M = (L + R) / 2;
        return f(query(l, r, 2 * k, L, M),
                 query(l, r, 2 * k + 1, M, R));
    }
};

using P = pair<ll, pll>;

struct Q {
    ll t, x, y;
};

int main() {
    int n, m, q;
    cin >> n >> m >> q;
    vector<P> pp(m);
    for (auto &i: pp) {
        cin >> i.second.first >> i.second.second >> i.first;
        i.second.first--;
    }
    vector<Q> query(q);
    for (auto &i: query) {
        cin >> i.x >> i.y >> i.t;
        i.x--;
    }
    map<ll, int> mp;
    for (auto [_, i]: pp) {
        mp[i.first] = 0;
        mp[i.second] = 0;
    }
    for (auto i: query) {
        mp[i.x] = 0;
        mp[i.y] = 0;
    }
    vector<int> idx(sz(mp));
    {
        int c = 0;
        for(auto &i : mp) {
            i.second = c;
            idx[c] = i.first;
            c++;
        }
    }
    vector<pll> w(idx.size() - 1);
    rep(i, sz(w)) {
        w[i] = {0, idx[i+ 1] - idx[i]};
    }

    for(auto &i : pp) {
        i.second.first = mp[i.second.first];
        i.second.second = mp[i.second.second];
    }
    for(auto &i : query) {
        i.x = mp[i.x];
        i.y = mp[i.y];
    }

    auto ff = [](pll x, pll y) {
        return make_pair(x.first + y.first,
                         x.second + y.second);
    };

    auto gg = [](pll x, ll y) {
                x.first += x.second * y;
                return x;
            };

    auto hh = [](ll x, ll y) { return  x + y;};

    vector<pll> ans(q, {0, 1e15});
    rep(cc, 50) {
        vector<pair<ll, int>> events;
        rep(i,q) {
            events.eb((ans[i].first + ans[i].second) / 2,
                      i + 1);
        }
        rep(i, m) {
            events.eb(pp[i].first, -i);
        }
        sort(all(events));
        LazySeg<pll, ll, decltype(ff), decltype(gg), decltype(hh)> lst(w, ff, gg, hh, {0, 0}, 0LL);
        for(auto [v, i] : events) {
            if(i > 0) {
                i--;
                ll s = lst.query(query[i].x, query[i].y).first;

//                cerr << v MM s << endl;

                if(query[i].t <= s) {
                    ans[i].second = v;
                } else {
                    ans[i].first = v;
                }
            } else {
                i *= -1;
                lst.apply(pp[i].second.first, pp[i].second.second, 1);
            }
        }
    }
    for(auto &i : ans) {
        cout << i.second << endl;
    }
}
accuracy: 1
time_ms: 5890
memory_kb: 80944
final_rank: 13

code_snippet: #line 2 "library/template/template.hpp"
//#pragma GCC target("avx")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define overload4(a,b,c,d,e,...) e
#define overload3(a,b,c,d,...) d
#define rep1(a) for(ll i=0;i<(ll)(a);i++)
#define rep2(i,a) for(ll i=0;i<(ll)(a);i++)
#define rep3(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep4(i,a,b,c) for(ll i=(ll)(a);i<(ll)(b);i+=(ll)(c))
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep1(a) for(ll i=(ll)(a)-1;i>=0;i--)
#define rrep2(i,a) for(ll i=(ll)(a)-1;i>=0;i--)
#define rrep3(i,a,b) for(ll i=(ll)(b)-1;i>=(ll)(a);i--)
#define rrep(...) overload3(__VA_ARGS__,rrep3,rrep2,rrep1)(__VA_ARGS__)
#define fore(...) for (auto&& __VA_ARGS__)
#define all1(i) begin(i),end(i)
#define all2(i,a) begin(i),begin(i)+a
#define all3(i,a,b) begin(i)+a,begin(i)+b
#define all(...) overload3(__VA_ARGS__,all3,all2,all1)(__VA_ARGS__)
#define rall(n) (n).rbegin(),(n).rend()
#define INT(...) int __VA_ARGS__;scan(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;scan(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;scan(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;scan(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;scan(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;scan(__VA_ARGS__)
#define pb push_back
#define eb emplace_back
#define END(...) {print(__VA_ARGS__);return;}
using namespace std;
using ll=long long;
using ull=unsigned long long;
using ld=long double;
using vl=vector<ll>;
using vi=vector<int>;
using vs=vector<string>;
using vc=vector<char>;
using vvl=vector<vl>;
using pi=pair<int,int>;
using pl=pair<ll,ll>;
using vvc=vector<vc>;
using vd=vector<double>;
using vp=vector<pl>;
using vb=vector<bool>;
constexpr int dx[8]={1,0,-1,0,1,-1,-1,1};
constexpr int dy[8]={0,1,0,-1,1,1,-1,-1};
constexpr ll MOD=1000000007;
constexpr ll mod=998244353;
constexpr ld EPS=1e-8;
constexpr ld PI=3.1415926535897932384626;
template<typename T,typename U>
ostream &operator<<(ostream&os,const pair<T,U>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T,typename U>
istream &operator>>(istream&is,pair<T,U>&p){is>>p.first>>p.second;return is;}
template<typename T>
ostream &operator<<(ostream&os,const vector<T>&v){for(auto it=v.begin();it!=v.end();){os<<*it<<((++it)!=v.end()?" ":"");}return os;}
template<typename T>
istream &operator>>(istream&is,vector<T>&v){for(T &in:v){is>>in;}return is;}
void scan(){}
template<class Head,class... Tail>
void scan(Head&head,Tail&... tail){cin>>head;scan(tail...);}
template<class T>
void print(const T &t){cout<<t<<'\n';}
template<class Head, class... Tail>
void print(const Head &head, const Tail &... tail){cout<<head<<' ';print(tail...);}
template<class... T>
void fin(const T &... a){print(a...);exit(0);}
template<typename T,typename U>
inline bool chmax(T&a,U b){return a<b&&(a=b,true);}
template<typename T,typename U>
inline bool chmin(T&a,U b){return a>b&&(a=b,true);}
template<typename T>
class infinity{
  public:
  static constexpr T MAX=numeric_limits<T>::max();
  static constexpr T MIN=numeric_limits<T>::min();
  static constexpr T value=numeric_limits<T>::max()/2;
  static constexpr T mvalue=numeric_limits<T>::min()/2;
};
#if __cplusplus <= 201402L
template<class T>constexpr T infinity<T>::value;
template<class T>constexpr T infinity<T>::mvalue;
template<class T>constexpr T infinity<T>::MAX;
template<class T>constexpr T infinity<T>::MIN;
#endif
template<typename T>constexpr T INF=infinity<T>::value;
constexpr long long inf=INF<ll>;
inline int popcnt(ull x){
#if __cplusplus>=202002L
return popcount(x);
#endif
x=(x&0x5555555555555555)+((x>>1)&0x5555555555555555);x=(x&0x3333333333333333)+((x>>2)&0x3333333333333333);x=(x&0x0f0f0f0f0f0f0f0f)+((x>>4)&0x0f0f0f0f0f0f0f0f);x=(x&0x00ff00ff00ff00ff)+((x>>8)&0x00ff00ff00ff00ff);x=(x&0x0000ffff0000ffff)+((x>>16)&0x0000ffff0000ffff);return (x&0x00000000ffffffff)+((x>>32)&0x00000000ffffffff);
}
template<typename T,typename=void>
struct is_specialize:false_type{};
template<typename T>
struct is_specialize<T,typename conditional<false,typename T::iterator, void>::type>:true_type{};
template<typename T>
struct is_specialize<T,typename conditional<false,decltype(T::first),void>::type>:true_type{};
template<typename T>
struct is_specialize<T,enable_if_t<is_integral<T>::value,void>>:true_type{};
void dump(const char&t){cerr<<t;}
void dump(const string&t){cerr<<t;}
void dump(const bool&t){cerr<<(t?"true":"false");}
template <typename T,enable_if_t<!is_specialize<T>::value,nullptr_t> =nullptr>
void dump(const T&t){cerr<<t;}
template<typename T>
void dump(const T&t,enable_if_t<is_integral<T>::value>* =nullptr){string tmp;if(t==infinity<T>::value||t==infinity<T>::MAX)tmp="inf";if(is_signed<T>::value&&(t==infinity<T>::mvalue||t==infinity<T>::MIN))tmp="-inf";if(tmp.empty())tmp=to_string(t);cerr<<tmp;}
template<typename T,typename U>
void dump(const pair<T,U>&);
template<typename T>
void dump(const T&t,enable_if_t<!is_void<typename T::iterator>::value>* =nullptr){cerr<<"{";for(auto it=t.begin();it!=t.end();){dump(*it);cerr<<(++it==t.end()?"":",");}cerr<<"}";}
template<typename T,typename U>
void dump(const pair<T,U>&t){cerr<<"(";dump(t.first);cerr<<",";dump(t.second);cerr<<")";}
void trace(){cerr<<endl;}
template<typename Head,typename... Tail>
void trace(Head&&head,Tail&&... tail){dump(head);if(sizeof...(tail))cerr<<",";trace(forward<Tail>(tail)...);}
#ifdef ONLINE_JUDGE
#define debug(...) (void(0))
#else
#define debug(...) do{cerr<<#__VA_ARGS__<<"=";trace(__VA_ARGS__);}while(0)
#endif
struct IOSetup{IOSetup(){cin.tie(nullptr);ios::sync_with_stdio(false);cout.tie(0);cout<<fixed<<setprecision(12);cerr<<fixed<<setprecision(12);}};
template<class F>struct REC{F f;REC(F&&f_):f(std::forward<F>(f_)){}template<class...Args>auto operator()(Args&&...args)const{return f(*this, std::forward<Args>(args)...);}};
/**
 * @brief Template(テンプレート)
*/
#line 2 "library/Data_Structure/lazy_segtree.hpp"
template<class S,S (*op)(S,S),S (*e)(),class F,S (*mapping)(F,S),F (*composition)(F,F),F (*id)()>
struct lazy_segtree{
  private:
  int _n,size=1,idx=0;
  vector<S>seq;
  vector<F>lazy;
  void update(int k){seq[k]=op(seq[k<<1],seq[k<<1^1]);}
  void all_apply(int k,F f){
    seq[k]=mapping(f,seq[k]);
    if(k<size)lazy[k]=composition(f,lazy[k]);
  }
  void eval(int k){
    all_apply(k<<1,lazy[k]);
    all_apply(k<<1^1,lazy[k]);
    lazy[k]=id();
  }
  public:
  lazy_segtree():lazy_segtree(0){}
  lazy_segtree(int n):lazy_segtree(vector<S>(n,e())){}
  lazy_segtree(const vector<S>&v):_n(int(v.size())){
    while(size<_n)size<<=1,idx++;
    seq=vector<S>(size<<1,e());
    lazy=vector<F>(size,id());
    for(int i=0;i<_n;i++)seq[size+i]=v[i];
    for(int i=size-1;i>=1;i--)update(i);
  }
  void set(int p,S x){
    p+=size;
    for(int i=idx;i>=1;i--)eval(p>>i);
    seq[p]=x;
    for(int i=1;i<=idx;i++)update(p>>i);
  }
  S operator[](int p){
    p+=size;
    for(int i=idx;i>=1;i--)eval(p>>i);
    return seq[p];
  }
  S query(int l,int r){
    if(l==r)return e();
    S sml=e(),smr=e();
    l+=size,r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    while(l<r){
      if(l&1)sml=op(sml,seq[l++]);
      if(r&1)smr=op(seq[--r],smr);
      l>>=1,r>>=1;
    }
    return op(sml,smr);
  }
  S all_query()const{return seq[1];}
  void apply(int p,F f){
    p+=size;
    for(int i=idx;i>=1;i--)eval(p>>i);
    seq[p]=mapping(f,seq[p]);
    for(int i=1;i<=idx;i++)update(p>>i);
  }
  void apply(int l,int r,F f){
    if(l==r)return ;
    l+=size;
    r+=size;
    for(int i=idx;i>=1;i--){
      if(((l>>i)<<i)!=l)eval(l>>i);
      if(((r>>i)<<i)!=r)eval(r>>i);
    }
    int l2=l,r2=r;
    while(l<r){
      if(l&1)all_apply(l++,f);
      if(r&1)all_apply(--r,f);
      l>>=1;
      r>>=1;
    }
    l=l2,r=r2;
    for(int i=1;i<=idx;i++){
      if(((l>>i)<<i)!=l)update(l>>i);
      if(((r>>i)<<i)!=r)update(r>>i);
    }
  }
};
/**
 * @brief Lazy Segment Tree(遅延セグメント木)
*/
#line 2 "library/Others/compressor.hpp"
template<class T,class comp=less<T>>
class compressor{
  private:
  vector<T>data;
  comp cmp;
  bool sorted=false;
  public:
  compressor():compressor(comp()){}
  compressor(const comp&cmp):cmp(cmp){}
  compressor(const vector<T>&dat,const comp&cmp=comp()):data(dat),cmp(cmp){}
  compressor(vector<T>&&dat,const comp&cmp=comp()):data(move(dat)),cmp(cmp){}
  compressor(initializer_list<T>li,const comp&cmp=comp()):data(li.begin(),li.end()),cmp(cmp){}
  void push_back(const T&v){assert(!sorted);data.push_back(v);}
  void push_back(T&&v){assert(!sorted);data.push_back(move(v));}
  void push(const vector<T>&v){
    assert(!sorted);
    const int n=data.size();
    data.resize(v.size()+n);
    for(int i=0;i<(int)v.size();i++)data[i+n]=v[i];
  }
  void build(){
    assert(!sorted);sorted=1;
    sort(data.begin(),data.end(),cmp);
    data.erase(unique(data.begin(),data.end(),[&](const T&l,const T&r)->bool{return !cmp(l,r)&&!cmp(r,l);}),data.end());
  }
  const T&operator[](int k)const&{
    assert(sorted);
    return data[k];
  }
  int get_index(const T&v)const{
    assert(sorted);
    return int(lower_bound(data.begin(),data.end(),v,cmp)-data.begin());
  }
  void press(vector<T>&v)const{
    assert(sorted);
    for(auto&&i:v)i=get_index(i);
  }
  vector<int>pressed(const vector<T>&v)const{
    assert(sorted);
    vector<int>ret(v.size());
    for(int i=0;i<(int)v.size();i++)ret[i]=get_index(v[i]);
    return ret;
  }
  int size()const{
    assert(sorted);
    return data.size();
  }
};
#line 4 "code.cpp"
pl op(pl a,pl b){return {a.first+b.first,a.second+b.second};}
pl e(){return pl{0,1};}
pl mapping(ll a,pl b){return {b.first+a*b.second,b.second};}
ll composition(ll a,ll b){return a+b;}
ll id(){return 0;}
int main(){
  LL(n,m,q);
  vector<array<ll,3>>x(m),y(q);
  compressor<ll>c1,c2;
  rep(i,m){
    scan(x[i][0],x[i][1],x[i][2]);
    x[i][0]--;
    c1.pb(x[i][0]),c1.pb(x[i][1]);
    c2.pb(x[i][2]);
  }
  rep(i,q){
    scan(y[i][0],y[i][1],y[i][2]);
    y[i][0]--;
    c1.pb(y[i][0]),c1.pb(y[i][1]);
  }
  c1.build(),c2.build();
  vector<vector<pl>>update(c2.size());
  rep(i,m)update[c2.get_index(x[i][2])].emplace_back(c1.get_index(x[i][0]),c1.get_index(x[i][1]));
  rep(i,q)y[i][0]=c1.get_index(y[i][0]),y[i][1]=c1.get_index(y[i][1]);
  vl l(q,-1),r(q,c2.size());
  while(true){
    bool f=false;
    vvl mid(c2.size());
    rep(i,q)if(l[i]+1<r[i])mid[(l[i]+r[i])/2].push_back(i),f=true;
    if(!f)break;
    vector<pl>seq(c1.size());
    rep(i,c1.size()-1)seq[i]={0,c1[i+1]-c1[i]};
    lazy_segtree<pl,op,e,ll,mapping,composition,id>seg(seq);
    rep(i,c2.size()){
      for(auto [l,r]:update[i])seg.apply(l,r,1);
      for(auto j:mid[i]){
        ll sum=seg.query(y[j][0],y[j][1]).first;
        if(sum<y[j][2])l[j]=i;
        else r[j]=i;
      }
    }
  }
  rep(i,q)print(c2[r[i]]);
}
accuracy: 1
time_ms: 1410
memory_kb: 50244
final_rank: 5

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

struct LazySegTree {
    int n;
    vector<long long>dat;
    vector<int>lazy;
    vector<int>lnode,rnode;
    int init() {
        dat.push_back(0);
        lazy.push_back(0);
        lnode.push_back(-1);
        rnode.push_back(-1);
        return dat.size()-1;
    }
    LazySegTree(int N) {
        n = 1;
        while(n < N) {
            n *= 2;
        }
        init();
    }
    void eval(int k,int l,int r) {
        if(lazy[k] == 0) return;
        if(r-l >= 2) {
            if(lnode[k] == -1) lnode[k] = init();
            if(rnode[k] == -1) rnode[k] = init();
            lazy[lnode[k]] += lazy[k];
            lazy[rnode[k]] += lazy[k];
        }
        dat[k] += 1ll*(r-l)*lazy[k];
        lazy[k] = 0;
    }
    void update_sub(int a,int b,int s,int k,int l,int r) {
        if(a <= l && r <= b) {
            lazy[k] += s;
        }
        else if(a < r && l < b) {
            if(lnode[k] == -1) lnode[k] = init();
            if(rnode[k] == -1) rnode[k] = init();
            update_sub(a,b,s,lnode[k],l,(l+r)/2);
            update_sub(a,b,s,rnode[k],(l+r)/2,r);
            dat[k] = dat[lnode[k]]+dat[rnode[k]]+1ll*(r-l)/2*(lazy[lnode[k]]+lazy[rnode[k]]);
        }
    }
    void update(int a,int b,int s) {
        update_sub(a,b,s,0,0,n);
    }
    long long query_sub(int a,int b,int k,int l,int r) {
        if(r <= a || b <= l) return 0;
        if(a <= l && r <= b) return 1ll*(r-l)*lazy[k]+dat[k];
        long long ans = 1ll*(min(r,b)-max(a,l))*lazy[k];
        if(lnode[k] != -1) ans += query_sub(a,b,lnode[k],l,(l+r)/2);
        if(rnode[k] != -1) ans += query_sub(a,b,rnode[k],(l+r)/2,r);
        return ans;
    }
    long long query(int a,int b) {
        return query_sub(a,b,0,0,n);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N,M,Q;
    cin >> N >> M >> Q;
    vector<int>a(M),b(M),v(M);
    for(int i = 0; i < M; i++) {
        cin >> a[i] >> b[i] >> v[i];
        a[i]--;
        b[i]--;
    }
    vector<int>x(Q),y(Q);
    vector<long long>J(Q);
    for(int i = 0; i < Q; i++) {
        cin >> x[i] >> y[i] >> J[i];
        x[i]--;
        y[i]--;
    }
    vector<int>l(Q),r(Q,1001001001);
    while(true) {
        bool flag = false;
        vector<array<int,3>>query;
        for(int i = 0; i < Q; i++) {
            if(l[i]+1 < r[i]) {
                flag = true;
                int mid = (l[i]+r[i])/2;
                query.push_back({mid,1,i});
            }
        }
        if(!flag) break;
        for(int i = 0; i < M; i++) {
            query.push_back({v[i],0,i});
        }
        sort(query.begin(),query.end());
        LazySegTree Seg(N);
        for(int i = 0; i < query.size(); i++) {
            if(query[i][1] == 0) {
                int L = a[query[i][2]],R = b[query[i][2]];
                Seg.update(L,R+1,1);
            }
            else {
                int L = x[query[i][2]],R = y[query[i][2]];
                if(Seg.query(L,R+1) >= J[query[i][2]]) {
                    r[query[i][2]] = query[i][0];
                }
                else {
                    l[query[i][2]] = query[i][0];
                }
            }
        }
    }
    for(int i = 0; i < Q; i++) {
        cout << r[i] << "\n";
    }
}
accuracy: 1
time_ms: 7380
memory_kb: 163748
final_rank: 14

code_snippet: #line 1 "a.cpp"
// cSpell:disable
/*	author:  Kite_kuma
	created: 2022.11.22 06:55:46 */

// #include "SPJ-Library/data_structure/rangeadd_rangesum_fenwicktree.hpp"
#line 2 "SPJ-Library/template/kuma.hpp"

#line 2 "SPJ-Library/template/basic_func.hpp"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool flag = true) { std::cout << (flag ? "Yes" : "No") << '\n'; }
void YES(bool flag = true) { std::cout << (flag ? "YES" : "NO") << '\n'; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(const T &x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(const Head &H, const Tail &... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T value) {
	for(auto &a : v) a += value;
	return;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

// ceil(a / b);
template <class T>
T dup(T a, T b) {
	assert(b);
	if(b < 0) {
		a *= -1;
		b *= -1;
	}
	return least_upper_multiple(a, b) / b;
}

long long pow_ll(long long a, long long n) {
	assert(n >= 0LL);
	if(n == 0) return 1LL;
	if(a == 0) return 0LL;
	if(a == 1) return 1LL;
	if(a == -1) return (n & 1LL) ? -1LL : 1LL;
	long long res = 1;
	while(n > 1LL) {
		if(n & 1LL) res *= a;
		a *= a;
		n >>= 1;
	}
	return res * a;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, const long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return (int)std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(const std::vector<T> &a) {
	std::vector<T> vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(const auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}
#line 1 "SPJ-Library/template/header.hpp"
#include <bits/stdc++.h>
#line 2 "SPJ-Library/template/io.hpp"

#line 4 "SPJ-Library/template/io.hpp"

#line 8 "SPJ-Library/template/debug.hpp"

#line 3 "SPJ-Library/template/constants.hpp"

constexpr int inf = 1000'000'000;
constexpr long long INF = 1'000'000'000'000'000'000LL;
constexpr int mod_1000000007 = 1000000007;
constexpr int mod_998244353 = 998244353;
const long double pi = acosl(-1.);
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
#line 10 "SPJ-Library/template/debug.hpp"

namespace viewer {

template <typename T, typename U>
void view(const std::pair<T, U> &p);

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p);

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p);

void view(const long long &e);

void view(const int &e);

template <typename T>
void view(const T &e);

template <typename T>
void view(const std::set<T> &s);

template <typename T>
void view(const std::unordered_set<T> &s);

template <typename T>
void view(const std::multiset<T> &s);

template <typename T>
void view(const std::unordered_multiset<T> &s);

template <typename T>
void view(const std::vector<T> &v);

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v);

template <typename T>
void view(const std::vector<std::vector<T>> &vv);

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v);

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v);

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v);

template <typename map_type>
void view_map_container(const map_type &m);

template <typename T, typename U>
void view(const std::map<T, U> &m);

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m);

template <typename container_type>
void view_container(const container_type &c, bool vertically = false) {
	typename container_type::const_iterator begin = c.begin();
	const typename container_type::const_iterator end = c.end();
	if(vertically) {
		std::cerr << "{\n";
		while(begin != end) {
			std::cerr << '\t';
			view(*(begin++));
			if(begin != end) std::cerr << ',';
			std::cerr << '\n';
		}
		std::cerr << '}';
		return;
	}
	std::cerr << "{ ";
	while(begin != end) {
		view(*(begin++));
		if(begin != end) std::cerr << ',';
		std::cerr << ' ';
	}
	std::cerr << '}';
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << '(';
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ')';
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ')';
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << '(';
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ')';
}

void view(const long long &e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int &e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T &e) {
	std::cerr << e;
}

template <typename T>
void view(const std::set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::unordered_multiset<T> &s) {
	view_container(s);
}

template <typename T>
void view(const std::vector<T> &v) {
	view_container(v);
}

template <typename T, std::size_t ary_size>
void view(const std::array<T, ary_size> &v) {
	view_container(v);
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	view_container(vv, true);
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	view_container(v, true);
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	view_container(v, true);
}

template <typename map_type>
void view_map_container(const map_type &m) {
	std::cerr << "{\n";
	for(typename map_type::const_iterator it = m.begin(); it != m.end(); it++) {
		std::cerr << "\t[";
		view(it->first);
		std::cerr << "] : ";
		view(it->second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	view_map_container(m);
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	view_map_container(m);
}

}  // namespace viewer

// when compiling : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(const T &x) {
	viewer::view(x);
}
template <typename Head, typename... Tail>
void debug_out(const Head &H, const Tail &... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
#line 2 "SPJ-Library/template/scanner.hpp"

#line 6 "SPJ-Library/template/scanner.hpp"

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#line 7 "SPJ-Library/template/io.hpp"

#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << ' ' << p.second;
	return os;
}

struct fast_io {
	fast_io() {
		std::ios::sync_with_stdio(false);
		std::cin.tie(nullptr);
		std::cout << std::fixed << std::setprecision(15);
		srand((unsigned)time(NULL));
	}
} fast_io_;
#line 2 "SPJ-Library/template/macros.hpp"

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;
#line 7 "SPJ-Library/template/kuma.hpp"

using namespace std;
#line 1 "atcoder/lazysegtree.hpp"



#line 8 "atcoder/lazysegtree.hpp"

#line 1 "atcoder/internal_bit.hpp"



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

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder


#line 10 "atcoder/lazysegtree.hpp"

namespace atcoder {

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        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;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        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() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(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 (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(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;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder


#line 8 "a.cpp"

using S = pair<ll, ll>;	 // len, sum;
S e() { return S(0LL, 0LL); }
S op(S a, S b) { return S(a.first + b.first, a.second + b.second); }
using F = ll;
F id() { return 0LL; }
S mapping(F f, S s) { return S(s.first, s.second + s.first * f); }
F composition(F f, F g) { return f + g; }

void solve(ll n, int m, int q) {
	vector<tuple<ll, ll, ll>> add_qs;
	vector<ll> values;
	vector<ll> places = {0, n};
	rep(m) {
		LL(a, b);
		LL(value);
		a--;
		values.push_back(value);
		places.push_back(a);
		places.push_back(b);
		add_qs.emplace_back(a, b, value);
	}
	unq_sort(values);
	auto value_to_id = [&values](ll value) -> int {
		auto it = lower_bound(all(values), value);
		return (it == values.end() || *it != value) ? -1 : int(it - values.begin());
	};
	vector<tuple<int, int, ll>> qs_origin;
	rep(q) {
		LL(x, y);
		LL(t);
		x--;
		qs_origin.emplace_back(x, y, t - 1);
		places.push_back(x);
		places.push_back(y);
	}
	unq_sort(places);
	auto place_to_id = [&places](ll place) -> int {
		auto it = lower_bound(all(places), place);
		return (it == places.end() || *it != place) ? -1 : int(it - places.begin());
	};

	vector<tuple<int, int, ll>> qs_shrinked;
	for(auto [x, y, t] : qs_origin) {
		qs_shrinked.emplace_back(place_to_id(x), place_to_id(y), t);
	}

	const int ps = int(places.size());
	vector<S> initial_vec(ps - 1);
	rep(i, ps - 1) { initial_vec[i] = S(places[i + 1] - places[i], 0LL); }
	const int vs = int(values.size());
	vector<int> ans_left(q, 0), ans_right(q, vs), ans_mid(q, vs / 2);

	vector<vector<pair<int, int>>> add_range_queries(vs);
	for(auto [a, b, v] : add_qs) add_range_queries.at(value_to_id(v)).emplace_back(place_to_id(a), place_to_id(b));

	rep(20) {
		// rangeadd_rangesum_fenwick_tree<ll> bit(n);
		atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> lst(initial_vec);
		vector<vector<int>> chkpts(vs);
		rep(i, q) {
			if(ans_left[i] + 1 == ans_right[i]) continue;
			chkpts[ans_mid[i]].push_back(i);
		}
		rep(value_id, vs) {
			foa(query_id, chkpts[value_id]) {
				int lef, rig;
				ll ord;
				tie(lef, rig, ord) = qs_shrinked[query_id];
				ll under = lst.prod(lef, rig).second;
				debug(value_id, query_id, lef, rig, under, ord);
				(under <= ord ? ans_left : ans_right)[query_id] = ans_mid[query_id];
				ans_mid[query_id] = ans_left[query_id] + (-ans_left[query_id] + ans_right[query_id]) / 2;
			}
			for(auto [lef, rig] : add_range_queries[value_id]) lst.apply(lef, rig, 1LL);
		}
	}

	foa(id, ans_left) { cout << values[id] << '\n'; }
	return;
}
int main() {
	int m, q;
	ll n;
	while(cin >> n >> m >> q && n + m + q) {
		solve(n, m, q);
	}
	return 0;
}
accuracy: 1
time_ms: 1430
memory_kb: 49756
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005,INF=1<<30;

// BIT セグ木 遅延セグ木 のみ

// from: https://gist.github.com/yosupo06/ddd51afb727600fd95d9d8ad6c3c80c9
// (based on AtCoder STL)

#include <algorithm>
#include <array>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
    namespace internal {
        int ceil_pow2(int n) {
            int x = 0;
            while ((1U << x) < (unsigned int)(n)) x++;
            return x;
        }
        int bsf(unsigned int n) {
#ifdef _MSC_VER
            unsigned long index;
            _BitScanForward(&index, n);
            return index;
#else
            return __builtin_ctz(n);
#endif
        }
    }  // namespace internal
    
}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

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 internal
    
}  // namespace atcoder

#include <cassert>
#include <vector>

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;
        }
    };
    
}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
namespace atcoder {
    
    template <class S,
    S (*op)(S, S),
    S (*e)(),
    class F,
    S (*mapping)(F, S),
    F (*composition)(F, F),
    F (*id)()>
    struct lazy_segtree {
    public:
        lazy_segtree() : lazy_segtree(0) {}
        lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
        lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
            log = internal::ceil_pow2(_n);
            size = 1 << log;
            d = std::vector<S>(2 * size, e());
            lz = std::vector<F>(size, id());
            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;
            for (int i = log; i >= 1; i--) push(p >> i);
            d[p] = x;
            for (int i = 1; i <= log; i++) update(p >> i);
        }
        
        S get(int p) {
            assert(0 <= p && p < _n);
            p += size;
            for (int i = log; i >= 1; i--) push(p >> i);
            return d[p];
        }
        
        S prod(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            if (l == r) return e();
            
            l += size;
            r += size;
            
            for (int i = log; i >= 1; i--) {
                if (((l >> i) << i) != l) push(l >> i);
                if (((r >> i) << i) != r) push(r >> i);
            }
            
            S sml = e(), smr = e();
            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() { return d[1]; }
        
        void apply(int p, F f) {
            assert(0 <= p && p < _n);
            p += size;
            for (int i = log; i >= 1; i--) push(p >> i);
            d[p] = mapping(f, d[p]);
            for (int i = 1; i <= log; i++) update(p >> i);
        }
        void apply(int l, int r, F f) {
            assert(0 <= l && l <= r && r <= _n);
            if (l == r) return;
            
            l += size;
            r += size;
            
            for (int i = log; i >= 1; i--) {
                if (((l >> i) << i) != l) push(l >> i);
                if (((r >> i) << i) != r) push((r - 1) >> i);
            }
            
            {
                int l2 = l, r2 = r;
                while (l < r) {
                    if (l & 1) all_apply(l++, f);
                    if (r & 1) all_apply(--r, f);
                    l >>= 1;
                    r >>= 1;
                }
                l = l2;
                r = r2;
            }
            
            for (int i = 1; i <= log; i++) {
                if (((l >> i) << i) != l) update(l >> i);
                if (((r >> i) << i) != r) update((r - 1) >> i);
            }
        }
        
        template <bool (*g)(S)> int max_right(int l) {
            return max_right(l, [](S x) { return g(x); });
        }
        template <class G> int max_right(int l, G g) {
            assert(0 <= l && l <= _n);
            assert(g(e()));
            if (l == _n) return _n;
            l += size;
            for (int i = log; i >= 1; i--) push(l >> i);
            S sm = e();
            do {
                while (l % 2 == 0) l >>= 1;
                if (!g(op(sm, d[l]))) {
                    while (l < size) {
                        push(l);
                        l = (2 * l);
                        if (g(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 (*g)(S)> int min_left(int r) {
            return min_left(r, [](S x) { return g(x); });
        }
        template <class G> int min_left(int r, G g) {
            assert(0 <= r && r <= _n);
            assert(g(e()));
            if (r == 0) return 0;
            r += size;
            for (int i = log; i >= 1; i--) push((r - 1) >> i);
            S sm = e();
            do {
                r--;
                while (r > 1 && (r % 2)) r >>= 1;
                if (!g(op(d[r], sm))) {
                    while (r < size) {
                        push(r);
                        r = (2 * r + 1);
                        if (g(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;
        std::vector<F> lz;
        
        void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
        void all_apply(int k, F f) {
            d[k] = mapping(f, d[k]);
            if (k < size) lz[k] = composition(f, lz[k]);
        }
        void push(int k) {
            all_apply(2 * k, lz[k]);
            all_apply(2 * k + 1, lz[k]);
            lz[k] = id();
        }
    };
    
}  // namespace atcoder

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

namespace atcoder {
    
    template <class S, S (*op)(S, S), S (*e)()> struct segtree {
    public:
        segtree() : segtree(0) {}
        segtree(int n) : segtree(std::vector<S>(n, e())) {}
        segtree(const std::vector<S>& v) : _n(int(v.size())) {
            log = internal::ceil_pow2(_n);
            size = 1 << log;
            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) {
            assert(0 <= p && p < _n);
            return d[p + size];
        }
        
        S prod(int l, int r) {
            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() { return d[1]; }
        
        template <bool (*f)(S)> int max_right(int l) {
            return max_right(l, [](S x) { return f(x); });
        }
        template <class F> int max_right(int l, F f) {
            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) {
            return min_left(r, [](S x) { return f(x); });
        }
        template <class F> int min_left(int r, F f) {
            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 T=pair<ll,int>;
using E=ll;

T f(T a,T b){
    return mp(a.fi+b.fi,a.se+b.se);
}

T g(E a,T b){
    return mp(b.fi+a*b.se,b.se);
}

E h(E a,E b){
    return a+b;
}

T ti(){
    return mp(0LL,1);
}

E ei(){
    return 0;
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N,M,Q;cin>>N>>M>>Q;
    vector<tuple<int,int,ll>> upd(M),que(Q);
    vector<ll> use,zahyou;
    for(int i=0;i<M;i++){
        int a,b;ll c;cin>>a>>b>>c;a--;
        upd[i]={a,b,c};
        use.push_back(c);
        zahyou.push_back(a);
        zahyou.push_back(b);
    }
    for(int i=0;i<Q;i++){
        int a,b;ll c;cin>>a>>b>>c;a--;
        que[i]={a,b,c};
        zahyou.push_back(a);
        zahyou.push_back(b);
    }
    sort(all(use));
    use.erase(unique(all(use)),use.end());
    
    sort(all(zahyou));
    zahyou.erase(unique(all(zahyou)),zahyou.end());
    
    vector<vector<pair<int,int>>> wh(si(use));
    
    for(int i=0;i<M;i++){
        auto [l,r,x]=upd[i];
        l=lower_bound(all(zahyou),l)-zahyou.begin();
        r=lower_bound(all(zahyou),r)-zahyou.begin();
        x=lower_bound(all(use),x)-use.begin();
        wh[x].push_back(mp(l,r));
    }
    
    for(int i=0;i<Q;i++){
        auto [l,r,x]=que[i];
        l=lower_bound(all(zahyou),l)-zahyou.begin();
        r=lower_bound(all(zahyou),r)-zahyou.begin();
        //x=lower_bound(all(use),x)-use.begin();
        que[i]={l,r,x};
    }
    
    vector<int> left(Q,-1),right(Q,si(use));
    
    while(1){
        bool upd=true;
        vector<vector<int>> mid(si(use));
        for(int i=0;i<Q;i++){
            if(right[i]-left[i]>1){
                upd=false;
                int xx=(left[i]+right[i])/2;
                mid[xx].push_back(i);
            }
        }
        if(upd) break;
        
        vector<T> def(si(zahyou));
        for(int i=0;i+1<si(zahyou);i++) def[i]=mp(0,zahyou[i+1]-zahyou[i]);
        atcoder::lazy_segtree<T,f,ti,E,g,h,ei> seg(def);
        
        for(int i=0;i<si(use);i++){
            for(auto [l,r]:wh[i]){
                seg.apply(l,r,1);
            }
            for(int q:mid[i]){
                auto [l,r,cn]=que[q];
                ll sum=seg.prod(l,r).fi;
                if(sum<cn) left[q]=i;
                else right[q]=i;
            }
        }
    }
    
    for(int q=0;q<Q;q++) cout<<use[right[q]]<<"\n";
}
accuracy: 1
time_ms: 1300
memory_kb: 46556
final_rank: 3