Cod sursa(job #2750523)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 11 mai 2021 19:07:50
Problema Progresie Scor 100
Compilator cpp-64 Status done
Runda Arhiva ICPC Marime 1.67 kb
#include <bits/stdc++.h>
#define int long long
#define sqr(x) ((x) * (x))

using namespace std;

ifstream fin("progresie.in");
ofstream fout("progresie.out");

void min_self(int &a, int b) {
  a = min(a, b);
}

void test_case() {
  int n, r;
  fin >> n >> r;
  for (int i = 1; ; ++i) {
    int V = i * (i - 1) + 1, rem = i - 1; /// incerc sa incep de la primul element al celui de-al i-lea block
    bool ok = true;
    for (int j = 1; j < n && ok; ++j) {
      int val = V + j * r;
      int block = sqrt(val - 1) + 1; /// in acest block ar trebui sa se afle valoarea
      int start_block = block * (block - 1) + 1, end_block = sqr(block); /// capetele block-ului
      if (val < start_block) { /// valoarea este una stearsa(adica se afla intre 2 block-uri), deci trebuie sa incrementez valoarea primului element al progresiei
        V += start_block - val;
        rem -= start_block - val; /// am avansat start_block - val pozitii
        val = start_block;
      } else min_self(rem, end_block - val); /// pentru a pastra pe parcurs fiecare valoare in block-ul destinat ei, ma asigur ca nu voi avansa in viitor astfel incat sa depasesc right bound-ul unui block
      if (val + rem < start_block) /// daca nu ma aflu in block-ul bun sau nu pot avansa pana la inceputul acestuia, solutia nu se afla in block-ul i, deci ma pot opri aici
        ok = false;
    }
    if (ok) { /// am gasit solutia
      fout << V << '\n';
      return;
    }
  }
}

void solve() {
  int T;
  fin >> T;
  for (int tc = 0; tc < T; ++tc)
    test_case();
}

void close_files() {
  fin.close();
  fout.close();
}

int32_t main() {
  solve();
  close_files();
  return 0;
}