Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- E. Два типа заклинаний
- ограничение по времени на тест 3.5 секунд
- ограничение по памяти на тест 256 мегабайт
- ввод стандартный ввод
- вывод стандартный вывод
- Поликарп играет в компьютерную игру (да, опять). В этой игре он сражается с монстрами при помощи заклинаний.
- Есть два типа заклинаний: огненный шар силы x наносит x урона монстру, а молния силы y наносит y урона монстру и удваивает урон следующего заклинания. Каждое заклинание может быть использовано только один раз, но Поликарп может применять их в любом порядке.
- Например, предположим, что Поликарп знает три заклинания: огненный шар силы 5, молнию силы 1 и молнию силы 8. Всего есть 6 способов выбрать порядок заклинаний:
- первое, второе, третье. В таком случае вы нанесете 5+1+2⋅8=22 урона;
- первое, третье, второе. В таком случае вы нанесете 5+8+2⋅1=15 урона;
- второе, первое, третье. В таком случае вы нанесете 1+2⋅5+8=19 урона;
- второе, третье, первое. В таком случае вы нанесете 1+2⋅8+2⋅5=27 урона;
- третье, первое, второе. В таком случае вы нанесете 8+2⋅5+1=19 урона;
- третье, второе, первое. В таком случае вы нанесете 8+2⋅1+2⋅5=20 урона.
- Изначально Поликарп знает 0 заклинаний. Его набор заклинаний меняется n раз, каждый раз он либо учит новое заклинание, либо забывает старое. После каждого изменения выведите максимально количество урона, которое можно нанести при помощи имеющихся заклинаний.
- Входные данные
- Первая строка содержит целое число n (1≤n≤2⋅105) — количество заклинаний в наборе.
- Каждая из следующих n строк содержит два числа tp и d (0≤tpi≤1; −109≤d≤109; di≠0) — описание изменений. Если tpi равно 0, Поликарп учит (или забывает) огненный шар, иначе он учит (или забывает) молнию.
- Если di>0, то Поликарп учит заклинание силы di. Иначе, Поликарп забывает заклинание силы −di, и гарантируется, что он знал это заклинание до этого.
- Гарантируется, что после каждого изменения все силы заклинаний различны (Поликарп не может знать одновременно два заклинания одинаковой силы).
- Выходные данные
- После каждого изменения выведите максимально количество урона, которое можно нанести при помощи имеющихся заклинаний.
- Пример
- входные данные
- 6
- 1 5
- 0 10
- 1 -5
- 0 5
- 1 11
- 0 -10
- выходные данные
- 5
- 25
- 10
- 15
- 36
- 21
- */
- use std::io;
- use std::collections::BTreeSet;
- use std::cmp::Ordering;
- fn main() {
- let mut n = String::new();
- io::stdin().read_line(&mut n).unwrap();
- let n = n.trim().parse::<i32>().unwrap();
- let mut balls = BTreeSet::<i32>::new();
- let mut light = BTreeSet::<i32>::new();
- let mut max= BTreeSet::<(i32, u8)>::new();
- for _i in 0..n {
- let mut input = String::new();
- io::stdin().read_line(&mut input).unwrap();
- let mut tup = input.split_whitespace();
- let kind = tup.next().unwrap().parse::<u8>().unwrap();
- let amount = tup.next().unwrap().parse::<i32>().unwrap();
- let mut sum: u128 = 0;
- match kind {
- 0 => {
- if amount < 0 {
- if balls.contains(&(-amount)) {
- balls.remove(&(-amount));
- } else {
- max.remove(&((-amount), kind));
- if balls.is_empty() {
- if !light.len() > 1 {
- let lightning = *light.iter().last().unwrap();
- max.insert((lightning, 1));
- light.remove(&lightning);
- }
- } else {
- if light.len() <= 1 {
- let ball = *balls.iter().last().unwrap();
- max.insert((ball, 0));
- balls.remove(&ball);
- } else {
- let ball = *balls.iter().last().unwrap();
- let lightning = *light.iter().last().unwrap();
- match ball.cmp(&lightning) {
- Ordering::Greater => {
- max.insert((ball, 0));
- balls.remove(&ball);
- }
- _ => {
- max.insert((lightning, 1));
- light.remove(&lightning);
- }
- }
- }
- }
- }
- } else {
- if max.is_empty() {
- match light.is_empty() {
- true => { balls.insert(amount); },
- false => {
- if !balls.is_empty() {
- let ball = *balls.iter().last().unwrap();
- if amount > ball {
- max.insert((amount, kind));
- } else {
- balls.remove(&ball);
- max.insert((ball, 0));
- balls.insert(amount);
- }
- } else {
- max.insert((amount, kind));
- }
- }
- };
- } else {
- let lightning = *light.iter().last().unwrap();
- if amount > ball {
- match amount.cmp(&lightning) {
- Ordering::Greater => max.insert((amount, 1)),
- _ => {
- max.insert((lightning, 1));
- light.remove(&lightning);
- light.insert(amount)
- }
- };
- } else {
- match ball.cmp(&lightning) {
- Ordering::Greater => {
- max.insert((ball, 0));
- balls.remove(&ball);
- }
- _ => {
- max.insert((lightning, 1));
- light.remove(&lightning);
- }
- }
- light.insert(amount);
- }
- }
- }
- }
- _ => {
- if amount < 0 {
- if light.contains(&(-amount)) {
- light.remove(&(-amount));
- if !max.is_empty() {
- let add = *max.iter().next().unwrap();
- max.remove(&add);
- match add.1 {
- 0 => balls.insert(add.0),
- _ => light.insert(add.0)
- };
- }
- } else {
- max.remove(&((-amount), kind));
- }
- } else {
- if balls.is_empty() {
- light.insert(amount);
- } else {
- let ball = *balls.iter().last().unwrap();
- if light.is_empty() {
- if !balls.is_empty() {
- let ball = *balls.iter().last().unwrap();
- max.insert((ball, 0));
- balls.remove(&ball);
- }
- light.insert(amount);
- } else {
- let lightning = *light.iter().last().unwrap();
- if amount > ball {
- match amount.cmp(&lightning) {
- Ordering::Greater => max.insert((amount, 1)),
- _ => {
- max.insert((lightning, 1));
- light.remove(&lightning);
- light.insert(amount)
- }
- };
- } else {
- match ball.cmp(&lightning) {
- Ordering::Greater => {
- max.insert((ball, 0));
- balls.remove(&ball);
- }
- _ => {
- max.insert((lightning, 1));
- light.remove(&lightning);
- }
- }
- light.insert(amount);
- }
- }
- }
- }
- }
- }
- for elem in &max {
- sum += (*elem).0 as u128 * 2;
- }
- if light.is_empty() && !max.is_empty() {
- sum -= (*max.iter().next().unwrap()).0 as u128;
- }
- for elem in &light {
- sum += *elem as u128;
- }
- for elem in &balls {
- sum += *elem as u128;
- }
- println!("{}\nballs: {:?} light: {:?}, max: {:?}", sum, balls, light, max);
- }
- }
Add Comment
Please, Sign In to add comment