結果
問題 |
No.449 ゆきこーだーの雨と雪 (4)
|
ユーザー |
|
提出日時 | 2016-11-21 20:43:40 |
言語 | D (dmd 2.109.1) |
結果 |
AC
|
実行時間 | 259 ms / 5,000 ms |
コード長 | 2,531 bytes |
コンパイル時間 | 1,062 ms |
コンパイル使用メモリ | 128,728 KB |
実行使用メモリ | 32,648 KB |
最終ジャッジ日時 | 2024-06-12 05:10:06 |
合計ジャッジ時間 | 11,766 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 43 |
ソースコード
import std.stdio; import std.array; import std.string; import std.conv; import std.algorithm; import std.typecons; import std.range; import std.random; import std.math; import std.container; class SegmentTree { int[] table; int N, table_size; this(int n) { N = n; table_size = 1; while (table_size < n) table_size *= 2; table_size *= 2; table = new int[](table_size); } void add(int pos, int num) { add_rec(0, 0, table_size/2-1, pos, num); } void add_rec(int i, int left, int right, int pos, int num) { table[i] += num; if (left == right) return; auto mid = (left + right) / 2; if (pos <= mid) add_rec(i*2+1, left, mid, pos, num); else add_rec(i*2+2, mid+1, right, pos, num); } int sum(int pl, int pr) { return sum_rec(0, pl, pr, 0, table_size/2-1); } int sum_rec(int i, int pl, int pr, int left, int right) { if (pl > right || pr < left) return 0; else if (pl <= left && right <= pr) return table[i]; else return sum_rec(i*2+1, pl, pr, left, (left+right)/2) + sum_rec(i*2+2, pl, pr, (left+right)/2+1, right); } } void main() { auto score(int a, int b) {return 50*a + 500*a/(8+2*b);}; alias Tuple!(int, "score", int, "order") Point; auto N = readln.chomp.to!int; auto L = readln.split.map!(to!int); Point[string] participants; Point[] points; auto ACed = new int[](N); auto T = readln.chomp.to!int; auto NP = new Tuple!(string, int, int)[](T); foreach (i; 0..T) { auto input = readln.split; if (input[1] == "?") { NP[i] = tuple(input[0], -1, -1); continue; } auto name = input[0]; auto prob = input[1][0].to!int - 'A'.to!int; ACed[prob] += 1; if (name in participants) participants[name] = Point(participants[name].score + score(L[prob], ACed[prob]), i); else participants[name] = Point(score(L[prob], ACed[prob]), i); points ~= Point(-participants[name].score, i); NP[i] = tuple(name, participants[name].score, i); } points.sort(); int[Point] ranks; foreach (i, p; points.enumerate) ranks[Point(-p.score, p.order)] = i.to!int; auto sg = new SegmentTree(100000); int[string] last; foreach (i; 0..T) { if (NP[i][2] == -1) { writeln(sg.sum(0, last[NP[i][0]])); } else { auto name = NP[i][0]; auto rank = ranks[Point(NP[i][1], NP[i][2])]; if (name in last) sg.add(last[name], -1); last[name] = rank; sg.add(rank, 1); } } }