結果

問題 No.1394 Changing Problems
ユーザー りあんりあん
提出日時 2021-02-13 00:25:51
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 143 ms / 3,000 ms
コード長 11,134 bytes
コンパイル時間 2,275 ms
コンパイル使用メモリ 206,768 KB
最終ジャッジ日時 2025-01-18 19:57:55
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 29
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#include<bits/stdc++.h>
#include <algorithm>
#include <cassert>
#include <vector>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
namespace internal {
int ceil_pow2(int n) {
int x = 0;
while ((1U << x) < (unsigned int)(n)) x++;
return x;
}
int bsf(unsigned int n) {
#ifdef _MSC_VER
unsigned long index;
_BitScanForward(&index, n);
return index;
#else
return __builtin_ctz(n);
#endif
}
} // namespace internal
} // namespace atcoder
namespace atcoder {
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
segtree() : segtree(0) {}
explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
log = internal::ceil_pow2(_n);
size = 1 << log;
d = std::vector<S>(2 * size, e());
for (int i = 0; i < _n; i++) d[size + i] = v[i];
for (int i = size - 1; i >= 1; i--) {
update(i);
}
}
void set(int p, S x) {
assert(0 <= p && p < _n);
p += size;
d[p] = x;
for (int i = 1; i <= log; i++) update(p >> i);
}
S get(int p) {
assert(0 <= p && p < _n);
return d[p + size];
}
S prod(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
S sml = e(), smr = e();
l += size;
r += size;
while (l < r) {
if (l & 1) sml = op(sml, d[l++]);
if (r & 1) smr = op(d[--r], smr);
l >>= 1;
r >>= 1;
}
return op(sml, smr);
}
S all_prod() { return d[1]; }
template <bool (*f)(S)> int max_right(int l) {
return max_right(l, [](S x) { return f(x); });
}
template <class F> int max_right(int l, F f) {
assert(0 <= l && l <= _n);
assert(f(e()));
if (l == _n) return _n;
l += size;
S sm = e();
do {
while (l % 2 == 0) l >>= 1;
if (!f(op(sm, d[l]))) {
while (l < size) {
l = (2 * l);
if (f(op(sm, d[l]))) {
sm = op(sm, d[l]);
l++;
}
}
return l - size;
}
sm = op(sm, d[l]);
l++;
} while ((l & -l) != l);
return _n;
}
template <bool (*f)(S)> int min_left(int r) {
return min_left(r, [](S x) { return f(x); });
}
template <class F> int min_left(int r, F f) {
assert(0 <= r && r <= _n);
assert(f(e()));
if (r == 0) return 0;
r += size;
S sm = e();
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!f(op(d[r], sm))) {
while (r < size) {
r = (2 * r + 1);
if (f(op(d[r], sm))) {
sm = op(d[r], sm);
r--;
}
}
return r + 1 - size;
}
sm = op(d[r], sm);
} while ((r & -r) != r);
return 0;
}
private:
int _n, size, log;
std::vector<S> d;
void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};
} // namespace atcoder
#include <cassert>
#include <vector>
#include <cassert>
#include <numeric>
#include <type_traits>
namespace atcoder {
namespace internal {
#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value ||
std::is_same<T, __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int128 =
typename std::conditional<std::is_same<T, __uint128_t>::value ||
std::is_same<T, unsigned __int128>::value,
std::true_type,
std::false_type>::type;
template <class T>
using make_unsigned_int128 =
typename std::conditional<std::is_same<T, __int128_t>::value,
__uint128_t,
unsigned __int128>;
template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
is_signed_int128<T>::value ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
std::is_signed<T>::value) ||
is_signed_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<(is_integral<T>::value &&
std::is_unsigned<T>::value) ||
is_unsigned_int128<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<
is_signed_int128<T>::value,
make_unsigned_int128<T>,
typename std::conditional<std::is_signed<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type>::type;
#else
template <class T> using is_integral = typename std::is_integral<T>;
template <class T>
using is_signed_int =
typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using is_unsigned_int =
typename std::conditional<is_integral<T>::value &&
std::is_unsigned<T>::value,
std::true_type,
std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
std::make_unsigned<T>,
std::common_type<T>>::type;
#endif
template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
} // namespace internal
} // namespace atcoder
namespace atcoder {
template <class T> struct fenwick_tree {
using U = internal::to_unsigned_t<T>;
public:
fenwick_tree() : _n(0) {}
explicit fenwick_tree(int n) : _n(n), data(n) {}
void add(int p, T x) {
assert(0 <= p && p < _n);
p++;
while (p <= _n) {
data[p - 1] += U(x);
p += p & -p;
}
}
T sum(int l, int r) {
assert(0 <= l && l <= r && r <= _n);
return sum(r) - sum(l);
}
private:
int _n;
std::vector<U> data;
U sum(int r) {
U s = 0;
while (r > 0) {
s += data[r - 1];
r -= r & -r;
}
return s;
}
};
} // namespace atcoder
using namespace std;
const int M = 1000000007;
using P = pair<int, int>;
struct node {
int max;
int idx;
int sum;
node() {}
node(int x, int i) : max(0), idx(i), sum(x) {}
node(int max, int idx, int sum) : max(max), idx(idx), sum(sum) {}
};
node merge(node a, node b) {
int sum = a.sum + b.sum;
int max, idx;
if (a.sum + b.max > a.max) {
max = a.sum + b.max;
idx = b.idx;
}
else {
max = a.max;
idx = a.idx;
}
return node(max, idx, sum);
}
node e() {
return node(-M, -M, 0);
}
int maa(int a, int b) {
return max(a, b);
}
int e2() {
return -M;
}
void hoge() {
int q;
cin >> q;
for (int _ = 0; _ < q; ++_) {
int i, x;
cin >> i >> x;
cout << x + 1 << '\n';
}
}
int main() {
cin.tie(0);
ios::sync_with_stdio(0);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
if (n == 1) {
hoge();
return 0;
}
vector<int> cnt(n - 1);
long long sum = 0;
for (int i = 0; i < n; ++i) {
++cnt[a[i] % (n - 1)];
sum += a[i] / (n - 1);
}
vector<node> v(n - 1);
for (int i = 0; i < n - 1; ++i) {
v[i] = node(cnt[i] - 1, i);
}
atcoder::segtree<node, merge, e> sg(v);
atcoder::segtree<int, maa, e2> sg2(a);
atcoder::fenwick_tree<int> bit(n - 1);
for (int i = 0; i < n - 1; ++i) {
bit.add(i, cnt[i]);
}
auto prod = [&](int l, int r) {
l %= n - 1;
r %= n - 1;
if (l < r) {
return sg.prod(l, r);
}
else {
node res1 = sg.prod(l, n - 1);
node res2 = sg.prod(0, r);
return merge(res1, res2);
}
};
int q;
cin >> q;
for (int _ = 0; _ < q; ++_) {
int i, x;
cin >> i >> x;
--i;
--cnt[a[i] % (n - 1)];
sg.set(a[i] % (n - 1), node(cnt[a[i] % (n - 1)] - 1, a[i] % (n - 1)));
bit.add(a[i] % (n - 1), -1);
sum -= a[i] / (n - 1);
a[i] = x;
++cnt[a[i] % (n - 1)];
sg.set(a[i] % (n - 1), node(cnt[a[i] % (n - 1)] - 1, a[i] % (n - 1)));
bit.add(a[i] % (n - 1), 1);
sum += a[i] / (n - 1);
sg2.set(i, x);
long long ma = sg2.prod(0, n);
if (ma <= n - 2) {
cout << 0 << '\n';
continue;
}
long long c = ma / (n - 1) * n - sum;
c -= bit.sum(ma % (n - 1) + 1, n - 1);
assert(c >= 0);
long long k = ma - (n - 2);
if (k <= c) {
cout << k << '\n';
continue;
}
// cout << k << ' ' << c << '\n';
node nd = prod(ma % (n - 1) + 1, ma % (n - 1) + 1 + n - 1);
// cout << nd.idx << ' ' << nd.max << ' ' << nd.sum << '\n';
int di = nd.idx - (ma % (n - 1) + 1);
while (di < 0) di += n - 1;
if (k - c <= nd.max) {
int ok = ma % (n - 1) + 1 + n - 1;
int ng = ma % (n - 1) + 1;
while (ng + 1 < ok) {
int mid = (ok + ng) / 2;
if (k - c <= prod(ma % (n - 1) + 1, mid).max) {
ok = mid;
}
else {
ng = mid;
}
}
di = ok - 1 - (ma % (n - 1) + 1);
// while (di < 0) di += n - 1;
cout << k + di << '\n';
continue;
}
k += di;
c += nd.max + di;
// cout << k << ' ' << c << '\n';
assert(k > c);
long long rem = k - c;
cout << k + rem * (n - 1) << '\n';
}
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0