Problem:
プログラミングコンテスト

白虎大学では毎年プログラミングコンテストが開催されています。チームの総数をNとしたとき、チームには1からNのチームIDがそれぞれ割り当てられています。コンテストは全てのチームの得点が0の状態から開始し、L秒間連続して行われます。

今年のコンテストは、テレビで中継されることになりました。コンテストの間テレビに映るのは、その時点で最も得点の高いチームだけです。ただし、該当するチームが複数いるときは、その中でチームIDの一番小さいチームが映ります。映すべきチームが変わると、瞬時にカメラが切り替わります。

あなたはコンテストのログを入手しました。ログには、あるチームの得点が変化した時のレコードがすべて含まれています。各レコードは「チームdがコンテスト開始t秒後の時点でx点獲得した」という形式で与えられています。なお、減点される場合もあるので、現在の得点が0より小さくなることもあります。

コンテストのログを入力とし、コンテスト開始から終了までの間にテレビに映った時間が最も長いチームのIDを報告するプログラムを作成してください。

入力

入力は1つのデータセットからなる。入力は以下の形式で与えられる。

N R L
d1 t1 x1
d2 t2 x2
:
dR tR xR

１行目は３つの整数からなる。N(2 ≤ N ≤ 100000)はチーム数、R(0 ≤ R ≤ 1000000)はログに含まれるレコードの数である。L(1 ≤ L ≤ 1000000)はコンテストの時間（長さ）を表す。続くR行に各レコードの情報が与えられる。各レコードはチームdi(1 ≤ di ≤ N)がコンテスト開始ti(0 < ti < L)秒後の時点でxi(-1000 ≤ xi ≤ 1000)点獲得あるいは減点されたことを示す。ただし、ti, xiは整数であり、ti-1 ≤ tiである。

出力

コンテスト開始から終了までの間にテレビに映った時間が最も長いチームのIDを１行に出力する。ただし、最も長いチームが複数あるときは、その中でチームIDの一番小さいチームを出力する。

入力例 1

3 4 600
3 100 5
1 200 10
2 400 20
3 500 20

出力例 1

1

入力例 2

3 5 600
3 100 5
1 200 10
2 300 30
1 400 -8
2 400 -27

出力例 2

3

Solution in C++ (judge verdict: Accepted)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>

using namespace std;

#define rep(i,j) REP((i), 0, (j))
#define REP(i,j,k) for(int i=(j);(i)<(k);++i)
#define BW(a,x,b) ((a)<=(x)&&(x)<=(b))
#define ALL(v) (v).begin(), (v).end()
#define LENGTHOF(x) (sizeof(x) / sizeof(*(x)))
#define AFILL(a, b) fill((int*)a, (int*)(a + LENGTHOF(a)), b)
#define MP make_pair
#define PB push_back
#define F first
#define S second
#define INF 1 << 30
#define EPS 1e-10
#define MAX_N 200000

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<int, P> pii;
typedef vector<int> vi;
typedef queue<int> qi;

struct segtree{
  int N;
  P dat[2 * MAX_N - 1];
  segtree(){}
  segtree(int n){
    N = 1;
    while(n > N) N *= 2;

    rep(i, 2 * N - 1) dat[i] = MP(-10000000, -10000000);
    for(int i = N - 1; i < 2 * N - 1; i++) dat[i] = MP(0, -1 * (i - N + 1));
  }

  void update(int k, int a){
    k += N - 1;
    dat[k].F += a;
    while(k > 0){
      k = (k - 1) / 2;
      dat[k] = max(dat[k*2+1], dat[2*k+2]);
    }
  }

  P query(int a, int b){ return query(a, b, 0, 0, N); }
  P query(int a, int b, int k, int l, int r){
    if(r <= a || b <= l) return P(-10000000, -10000000);

    if(a <= l && r <= b) return dat[k];
    else{
      P vl = query(a, b, 2*k+1, l, (l+r)/2);
      P vr = query(a, b, 2*k+2, (l+r)/2, r);
      return max(vl, vr);
    }
  }
};

int res[MAX_N];

int main(){
  int N, R, L;
  scanf("%d%d%d", &N, &R, &L);
  segtree seg(N);
  rep(i, N) seg.update(i, 0);

  int time = 0;
  rep(i, R){
    int d, t, x;
    scanf("%d%d%d", &d, &t, &x); d--;
    P s = seg.query(0, N);
    res[-s.second] += t - time;
    seg.update(d, x);
    time = t;
  }
  P s = seg.query(0, N);
  res[-s.second] += L - time;

  int ans = 0;
  rep(i, N) if(res[ans] < res[i]) ans = i;

  printf("%d\n", ans+1);
  return 0;
}