結果
| 問題 |
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);
}
}
}