結果
| 問題 | No.3017 交互浴 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-05-23 20:44:16 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 227 ms / 2,000 ms |
| コード長 | 9,806 bytes |
| 記録 | |
| コンパイル時間 | 1,184 ms |
| コンパイル使用メモリ | 122,876 KB |
| 実行使用メモリ | 9,856 KB |
| 最終ジャッジ日時 | 2026-05-23 20:44:44 |
| 合計ジャッジ時間 | 16,279 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge2_0 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 55 |
ソースコード
#include<iostream>
#include<iomanip>
#include<vector>
#include<queue>
#include<set>
#include<math.h>
using namespace std;
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define REP(i, l, r) rep(i, l, r + 1)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
using ll = long long;
using ld = long double;
struct Edge {
int to;
ll w;
};
using Graph = vector<vector<int>>;
// using Graph = vector<vector<Edge> >;
const ll INF = 2e18;
// const int INF = 2e9;
template <class T> using vc = vector<T>;
template <class T> using vv = vector<vector<T>>;
template <class T> using vvv = vector<vector<vector<T>>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;
template <class T> istream &operator>>(istream &i, vc<T> &v) {
rep(j, 0, v.size()) i >> v[j];
return i;
}
template <class T> ostream &operator<<(ostream &o, vc<T> &v) {
rep(j, 0, v.size()) o << v[j] << " ";
return o;
}
template <class T> bool chmin(T &a, T b) {
if (a > b) {
a = b;
return true;
}
return false;
}
template <class T> bool chmax(T &a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
constexpr double EPS = 1e-9;
inline bool eq(double a, double b) { return fabs(a - b) < EPS; }
inline bool lt(double a, double b) { return a < b - EPS; }
inline bool gt(double a, double b) { return a > b + EPS; }
inline int sgn(double x) {
if (x > EPS) return 1;
if (x < -EPS) return -1;
return 0;
}
// Interval Set
// T: type of range, VAL: data type
template<class T, class VAL = long long> struct IntervalSet {
struct Node {
T l, r;
VAL val;
Node(const T &l, const T &r, const VAL &val) : l(l), r(r), val(val) {}
constexpr bool operator < (const Node &rhs) const {
if (l != rhs.l) return l < rhs.l;
else return r < rhs.r;
}
friend ostream& operator << (ostream &s, const Node &e) {
return s << "([" << e.l << ", " << e.r << "): " << e.val << ")";
}
};
// internal values
const VAL identity;
set<Node> S;
// constructor
IntervalSet(const VAL &identity = VAL()) : identity(identity) {}
IntervalSet(const vector<VAL> &v, const VAL &identity = VAL()) : identity(identity) {
vector<Node> vec;
for (int l = 0; l < (int)v.size();) {
int r = l;
while (r < (int)v.size() && v[r] == v[l]) r++;
vec.emplace_back(l, r, v[l]);
l = r;
}
S = set<Node>(vec.begin(), vec.end());
}
// get the basic iterators
constexpr typename set<Node>::iterator begin() { return S.begin(); }
constexpr typename set<Node>::iterator end() { return S.end(); }
// get the iterator of interval which contains p
// not exist -> S.end()
constexpr typename set<Node>::iterator get(const T &p) {
auto it = S.upper_bound(Node(p, numeric_limits<T>::max(), 0));
if (it == S.begin()) return S.end();
it = prev(it);
if (it->l <= p && p < it->r) return it;
else return S.end();
}
// get the leftist iterator of interval which contains value >= p
constexpr typename set<Node>::iterator lower_bound(const T &p) {
auto it = get(p);
if (it != S.end()) return it;
return S.upper_bound(Node(p, numeric_limits<T>::max(), 0));
}
// exist the interval which contains p: true, [l, r): true
constexpr bool covered(const T &p) {
auto it = get(p);
if (it != S.end()) return true;
else return false;
}
constexpr bool covered(const T &l, const T &r) {
assert(l <= r);
if (l == r) return true;
auto it = get(l);
if (it != S.end() && r <= it->r) return true;
else return false;
}
// is p, q in same interval?
constexpr bool same(const T &p, const T &q) {
if (!covered(p) || !covered(q)) return false;
return get(p) == get(q);
}
// get the value of interval which contains p
// not exist -> identity
constexpr VAL get_val(const T &p) {
auto it = get(p);
if (it != S.end()) return it->val;
else return identity;
}
VAL operator [] (const T &p) const {
return get_val(p);
}
// get mex (>= p)
constexpr T get_mex(const T &p = 0) {
auto it = S.upper_bound(Node(p, numeric_limits<T>::max(), 0));
if (it == S.begin()) return p;
it = prev(it);
if (it->l <= p && p < it->r) return it->r;
else return p;
}
// update [l, r) with value val / insert [l, r)
// del: reflect effects of interval-delete
// add: reflect effects of interval-add
// add and del should be reversed operation each other
template<class ADDFUNC, class DELFUNC> void update(T l, T r, const VAL &val, const ADDFUNC &add, const DELFUNC &del) {
auto it = S.lower_bound(Node(l, 0, val));
while (it != S.end() && it->l <= r) {
if (it->l == r) {
if (it->val ==val) {
r = it->r;
del(it->l, it->r, it->val);
it = S.erase(it);
}
break;
}
if (it->r <= r) {
del(it->l, it->r, it->val);
it = S.erase(it);
} else {
if (it->val == val) {
r = it->r;
del(it->l, it->r, it->val);
it = S.erase(it);
} else {
Node node = *it;
del(it->l, it->r, it->val);
it = S.erase(it);
it = S.emplace_hint(it, r, node.r, node.val);
add(it->l, it->r, it->val);
}
}
}
if (it != S.begin()) {
it = prev(it);
if (it->r == l) {
if (it->val == val) {
l = it->l;
del(it->l, it->r, it->val);
it = S.erase(it);
}
} else if (l < it->r) {
if (it->val == val) {
l = min(l, it->l);
r = max(r, it->r);
del(it->l, it->r, it->val);
it = S.erase(it);
} else {
if (r < it->r) {
it = S.emplace_hint(next(it), r, it->r, it->val);
add(it->l, it->r, it->val);
it = prev(it);
}
Node node = *it;
del(it->l, it->r, it->val);
it = S.erase(it);
it = S.emplace_hint(it, node.l, l, node.val);
add(it->l, it->r, it->val);
}
}
}
if (it != S.end()) it = next(it);
it = S.emplace_hint(it, l, r, val);
add(it->l, it->r, it->val);
}
void update(const T &l, const T &r, const VAL &val) {
update(l, r, val, [](T, T, VAL){}, [](T, T, VAL){});
}
template<class ADDFUNC, class DELFUNC> void insert(T l, T r, const ADDFUNC &add, const DELFUNC &del) {
update(l, r, VAL(), add, del);
}
void insert(const T &l, const T &r) {
update(l, r, VAL(), [](T, T, VAL){}, [](T, T, VAL){});
}
// erase [l, r)
// del: reflect effects of interval-delete
// add: reflect effects of interval-add
// add and del should be reversed operation each other
template<class ADDFUNC, class DELFUNC> void erase(T l, T r, const ADDFUNC &add, const DELFUNC &del) {
auto it = S.lower_bound(Node(l, 0, VAL()));
//COUT(*it);
while (it != S.end() && it->l <= r) {
if (it->l == r) break;
if (it->r <= r) {
del(it->l, it->r, it->val);
it = S.erase(it);
} else {
Node node = *it;
del(it->l, it->r, it->val);
it = S.erase(it);
it = S.emplace_hint(it, r, node.r, node.val);
add(it->l, it->r, it->val);
}
}
if (it != S.begin()) {
it = prev(it);
if (l < it->r) {
if (r < it->r) {
it = S.emplace_hint(next(it), r, it->r, it->val);
add(it->l, it->r, it->val);
it = prev(it);
}
Node node = *it;
//COUT(*it);
del(it->l, it->r, it->val);
it = S.erase(it);
it = S.emplace_hint(it, node.l, l, node.val);
add(it->l, it->r, it->val);
//COUT(*it);
}
}
}
void erase(const T &l, const T &r) {
erase(l, r, [](T, T, VAL){}, [](T, T, VAL){});
}
// debug
friend ostream& operator << (ostream &s, const IntervalSet &ins) {
for (auto e : ins.S) {
s << "([" << e.l << ", " << e.r << "): " << e.val << ") ";
}
return s;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(10);
IntervalSet<int,int>is(2e9);
int ans=0;
auto add=[&](int l,int r,int v){ans+=v*(r-l);};
auto del=[&](int l,int r,int v){ans-=v*(r-l);};
int N;cin>>N;
rep(i,0,N){
int h;cin>>h;
if(i%2==0)is.update(0,h,1,add,del);
else is.update(0,h,0,add,del);
cout<<ans<<endl;
}
return 0;
}