Problem:
F - Acceleration of Network

インターネットと言う広大な海は少しずつ黒く塗りつぶされていった。

ボットの反乱、DDOS攻撃の嵐、ウィルスの蔓延、

何度も何度も繰り返されたクラッカーとの戦争で、人もインターネットもボロボロになった。

人の手では、インターネットはどうにもならない。

だから人は、とんでもない時間をかけて

インターネットを復旧できる「少女」を造った。

少女は、インターネットの手当をはじめた。

果てしなく広いインターネットの世界をどうにかしようと頑張った。

まだ少女ひとりでは撚り対線を織る事くらいしかできないけど、

長い長い時がすぎてインターネットが少し復旧すれば、

みんなと一緒に頑張れるだろうという期待をこめて。

問題文

少女はかつてインターネットに存在した N 個のサービスを復旧するために日々頑張っている．
現在を 0 日目とする．
インターネットがどの程度復旧しているかを復旧度という指標で表し，現在の復旧度は 0 であるとする．
少女は毎日作業をし，復旧度を 1 日につき 1 ずつ上げていく．
任意のまだ復旧していないサービス i は，復旧度が wi 以上になると自動的に復旧する．
サービス i が復旧すると，みんなが手伝ってくれることにより，復旧した次の日から xi 日間だけ作業がはかどり，復旧度の増加が加速する．
サービスには 3 つの種類があり，種類によって復旧度がどの程度増加するのかが異なる．
サービスの種類を 0, 1, 2 の番号で表すとする．
サービス i の種類を ti (∈ {0, 1, 2}) とすると，
サービス i が復旧してから d-1 日目から d 日目にかけて (1 ≤ d ≤ xi)，
ti=0 の場合は 1，
ti=1 の場合は d，
そして ti=2 の場合は d2 だけ，少女の作業とは別に復旧度が増加する．
また，同時に複数のサービスが復旧している場合，それぞれのサービスは独立に並行して復旧度を増加させる．

少女はサービスが復旧するまでにとんでもない時間がかかると思ったので，現在から何日目にサービスが復旧するか調べることにした．
またある日にち yj に復旧度がいくらになっているかも気になったので，それも Q 日分だけ調べることにした．

入力形式

入力は以下の形式で与えられる．

N Q
w1 t1 x1
...
wN tN xN
y1
...
yQ

出力形式

最初に N 行出力し，i 行目にはサービス i の復旧する日にちを出力せよ．次に Q 行出力し，j 行目には yj 日目に復旧度がいくらになっているかを出力せよ．
サービスが復旧する日にちが 3,652,425 を超える場合はMany years laterと出力せよ．

制約

0 ≤ N ≤ 105

1 ≤ Q ≤ 105

0 ≤ wi < 260

wi ≤ wi+1 (1 ≤ i < N)

ti ∈ {0, 1, 2}

1 ≤ xi ≤ 104

0 ≤ yj ≤ 3,652,425

yj < yj+1 (1 ≤ j < Q)

入力値はすべて整数である．

この問題の判定には，15 点分のテストケースのグループが設定されている．このグループに含まれるテストケースは上記の制約に加えて下記の制約も満たす．

N,Q,wi,yj ≤ 1,000

注意

0 日目の復旧度は 0 である．

wi=0 の時，サービス i は 0 日目に復旧する．

入出力例

入力例1

3 11
1 0 2
4 1 3
7 2 4
0
1
2
3
4
5
6
7
8
9
10

出力例1

1
3
4
0
1
3
5
7
11
19
29
46
47
48

入力例2

5 5
10000 0 20
10000 1 30
10000 0 40
10000 2 70
30000 2 10000
5000
10000
15000
20000
25000

出力例2

10000
10000
10000
10000
10039
5000
10000
40711690801
329498273301
333383477320

入力例3

2 2
3652425 0 1
3652426 2 10000
3652424
3652425

出力例3

3652425
Many years later
3652424
3652425

2つ目のサービスは復旧する日にちが 3,652,425 日を超えているのでMany years laterと出力している．

Writer : 森槙悟
Tester : 田村和範

Solution in JAVA (judge verdict: Accepted)

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Set;

//Acceleration of Network
public class Main{

	long[] w;
	int[] t, x;
	Map<Integer, Set<Integer>> s0 = new HashMap<Integer, Set<Integer>>(), s1 = new HashMap<Integer, Set<Integer>>(), s2 = new HashMap<Integer, Set<Integer>>();
	Map<Integer, Set<Integer>> e0 = new HashMap<Integer, Set<Integer>>(), e1 = new HashMap<Integer, Set<Integer>>(), e2 = new HashMap<Integer, Set<Integer>>();

	void reg(Map<Integer, Set<Integer>> set, int day, int id){
		if(set.containsKey(day))set.get(day).add(id);
		else{
			Set<Integer> s = new HashSet<Integer>();
			s.add(id);
			set.put(day, s);
		}
	}
	
	void run(){
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt(), Q = sc.nextInt(), L = 3652425;
		w = new long[N];
		t = new int[N]; x = new int[N];
		PriorityQueue<Integer> qw = new PriorityQueue<Integer>(N+1, new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				return Long.signum(w[o1]-w[o2]);
			}
		});
		int[] res = new int[N];
		long[] y = new long[L+1];
		Arrays.fill(res, L+1);
		long d1 = 0, d2 = 0, dt1 = 0, dt2 = 0;
		int n0 = 0, n2 = 0;
		for(int i=0;i<N;i++){
			w[i] = sc.nextLong(); t[i] = sc.nextInt(); x[i] = sc.nextInt();
			if(w[i]==0){
				res[i] = 0;
				if(t[i]==0){
					reg(s0, 1, i);
					reg(e0, x[i]+1, i);
				}
				else if(t[i]==1){
					reg(s1, 1, i);
					reg(e1, x[i]+1, i);
				}
				else{
					reg(s2, 1, i);
					reg(e2, x[i]+1, i);
				}
			}
			else qw.add(i);
		}
		for(int i=1;i<=L;i++){
			y[i] = y[i-1]+1;
			if(s0.containsKey(i)){
				n0+=s0.get(i).size();
			}
			if(e0.containsKey(i)){
				n0-=e0.get(i).size();
			}
			y[i]+=n0;
			if(s1.containsKey(i)){
				dt1+=s1.get(i).size();
			}
			if(e1.containsKey(i)){
				dt1-=e1.get(i).size();
				for(int id:e1.get(i))d1-=x[id];
			}
			d1+=dt1;
			y[i]+=d1;
			if(s2.containsKey(i)){
				int D = s2.get(i).size();
				n2+=D;
				dt2-=D;
			}
			if(e2.containsKey(i)){
				int D = e2.get(i).size();
				for(int id:e2.get(i)){
					dt2-=2*x[id]-1;
					d2-=x[id]*x[id];
				}
				n2-=D;
			}
			dt2+=2*n2;
			d2+=dt2;
			y[i]+=d2;
			while(!qw.isEmpty() && w[qw.peek()]<=y[i]){
				int id = qw.poll();
				res[id] = i;
				if(t[id]==0){
					reg(s0, i+1, id);
					reg(e0, i+x[id]+1, id);
				}
				else if(t[id]==1){
					reg(s1, i+1, id);
					reg(e1, i+x[id]+1, id);
				}
				else{
					reg(s2, i+1, id);
					reg(e2, i+x[id]+1, id);
				}
			}
		}
		for(int i=0;i<N;i++)System.out.println(L<res[i]?"Many years later":res[i]);
		while(Q--!=0)System.out.println(y[sc.nextInt()]);
	}
	
	public static void main(String[] args) {
		new Main().run();
	}
}