結果
| 問題 |
No.674 n連勤
|
| コンテスト | |
| ユーザー |
ei1333333
|
| 提出日時 | 2018-04-13 23:34:38 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 183 ms / 2,000 ms |
| コード長 | 3,603 bytes |
| コンパイル時間 | 2,630 ms |
| コンパイル使用メモリ | 213,696 KB |
| 最終ジャッジ日時 | 2025-01-05 10:08:34 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:101:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
101 | scanf("%lld %lld", &D, &Q);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~
main.cpp:104:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
104 | scanf("%lld %lld", &A[i], &B[i]);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
using namespace std;
template< typename Monoid, typename OperatorMonoid = Monoid >
struct LazySegmentTree {
using F = function< Monoid(Monoid, Monoid) >;
using G = function< Monoid(Monoid, OperatorMonoid, int) >;
using H = function< OperatorMonoid(OperatorMonoid, OperatorMonoid) >;
int sz;
vector< Monoid > data;
vector< OperatorMonoid > lazy;
const F f;
const G g;
const H h;
const Monoid M1;
const OperatorMonoid OM0;
LazySegmentTree(int n, const F f, const G g, const H h,
const Monoid &M1, const OperatorMonoid OM0)
: f(f), g(g), h(h), M1(M1), OM0(OM0) {
sz = 1;
while(sz < n) sz <<= 1;
data.assign(2 * sz, M1);
lazy.assign(2 * sz, OM0);
}
void set(int k, const Monoid &x) {
data[k + sz] = x;
}
void build() {
for(int k = sz - 1; k > 0; k--) {
data[k] = f(data[2 * k + 0], data[2 * k + 1]);
}
}
void propagate(int k, int len) {
if(lazy[k] != OM0) {
if(k < sz) {
lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
}
data[k] = g(data[k], lazy[k], len);
lazy[k] = OM0;
}
}
Monoid update(int a, int b, const OperatorMonoid &x, int k, int l, int r) {
propagate(k, r - l);
if(r <= a || b <= l) {
return data[k];
} else if(a <= l && r <= b) {
lazy[k] = h(lazy[k], x);
propagate(k, r - l);
return data[k];
} else {
return data[k] = f(update(a, b, x, 2 * k + 0, l, (l + r) >> 1),
update(a, b, x, 2 * k + 1, (l + r) >> 1, r));
}
}
Monoid update(int a, int b, const OperatorMonoid &x) {
return update(a, b, x, 1, 0, sz);
}
Monoid query(int a, int b, int k, int l, int r) {
propagate(k, r - l);
if(r <= a || b <= l) {
return M1;
} else if(a <= l && r <= b) {
return data[k];
} else {
return f(query(a, b, 2 * k + 0, l, (l + r) >> 1),
query(a, b, 2 * k + 1, (l + r) >> 1, r));
}
}
Monoid query(int a, int b) {
return query(a, b, 1, 0, sz);
}
Monoid operator[](const int &k) {
return query(k, k + 1);
}
};
using int64 = long long;
struct node {
int64 left, right, ans, len;
};
int main() {
int64 D, Q, A[30000], B[30000];
scanf("%lld %lld", &D, &Q);
vector< int64 > vs;
for(int i = 0; i < Q; i++) {
scanf("%lld %lld", &A[i], &B[i]);
for(int j = -1; j <= 1; j++) vs.push_back(A[i] + j);
for(int j = -1; j <= 1; j++) vs.push_back(B[i] + j);
}
sort(begin(vs), end(vs));
vs.erase(unique(begin(vs), end(vs)), end(vs));
node np = (node) {0, 0, 0, 0};
auto f = [](const node &x, const node &y) {
node z;
z.len = x.len + y.len;
z.left = x.left;
if(x.left == x.len) z.left += y.left;
z.right = y.right;
if(y.right == y.len) z.right += x.right;
z.ans = max(x.right + y.left, max(x.ans, y.ans));
z.ans = max(z.ans, max(z.left, z.right));
return z;
};
auto gg = [](const node &x, bool y, int len) {
node z = x;
z.ans = z.left = z.right = x.len;
return z;
};
auto h = [&](bool x, bool y) {
return x || y;
};
LazySegmentTree< node, bool > seg(vs.size(), f, gg, h, np, 0);
for(int i = 0; i + 1 < vs.size(); i++) {
seg.set(i, (node) {0, 0, 0, vs[i + 1] - vs[i]});
}
seg.build();
for(int i = 0; i < Q; i++) {
A[i] = lower_bound(begin(vs), end(vs), A[i]) - begin(vs);
B[i] = upper_bound(begin(vs), end(vs), B[i]) - begin(vs);
seg.update(A[i], B[i], true);
printf("%lld\n", seg.query(0, vs.size()).ans);
}
}
ei1333333