結果
問題 | No.992 最長増加部分列の数え上げ |
ユーザー |
![]() |
提出日時 | 2020-02-14 22:45:26 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 187 ms / 2,000 ms |
コード長 | 6,054 bytes |
コンパイル時間 | 1,961 ms |
コンパイル使用メモリ | 182,912 KB |
実行使用メモリ | 13,968 KB |
最終ジャッジ日時 | 2024-10-06 13:02:55 |
合計ジャッジ時間 | 8,967 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 42 |
ソースコード
#include <bits/stdc++.h>using namespace std;using LL = long long int;#define incID(i, l, r) for(int i = (l) ; i < (r); ++i)#define decID(i, l, r) for(int i = (r) - 1; i >= (l); --i)#define incII(i, l, r) for(int i = (l) ; i <= (r); ++i)#define decII(i, l, r) for(int i = (r) ; i >= (l); --i)#define inc(i, n) incID(i, 0, n)#define dec(i, n) decID(i, 0, n)#define inc1(i, n) incII(i, 1, n)#define dec1(i, n) decII(i, 1, n)#define inID(v, l, r) ((l) <= (v) && (v) < (r))#define inII(v, l, r) ((l) <= (v) && (v) <= (r))#define PB push_back#define EB emplace_back#define MP make_pair#define FI first#define SE second#define FR front()#define BA back()#define ALL(v) v.begin(), v.end()#define RALL(v) v.rbegin(), v.rend()auto setmin = [](auto & a, auto b) { return (b < a ? a = b, true : false); };auto setmax = [](auto & a, auto b) { return (b > a ? a = b, true : false); };auto setmineq = [](auto & a, auto b) { return (b <= a ? a = b, true : false); };auto setmaxeq = [](auto & a, auto b) { return (b >= a ? a = b, true : false); };#define SI(v) static_cast<int>(v.size())#define RF(e, v) for(auto & e: v)#define until(e) while(! (e))#define if_not(e) if(! (e))#define ef else if#define UR assert(false)#define IN(T, ...) T __VA_ARGS__; IN_(__VA_ARGS__);void IN_() { };template<typename T, typename ... U> void IN_(T & a, U & ... b) { cin >> a; IN_(b ...); };template<typename T> void OUT(T && a) { cout << a << endl; }template<typename T, typename ... U> void OUT(T && a, U && ... b) { cout << a << " "; OUT(b ...); }// ---- ----template<typename T> class SegmentTree {private:int n, s;vector<T> a;function<T(T &, T &)> f;T e;bool ok;public:SegmentTree() { n = 0; }SegmentTree(int nn, function<T(T &, T &)> ff, T ee) { init(nn, ff, ee); }void init(int nn, function<T(T &, T &)> ff, T ee) {n = nn;f = ff;e = ee;s = 1;while(s < n) { s *= 2; }a = vector<T>(2 * s, e);ok = true;}void shift(int & p) {assert(inID(p, 0, n));p += s;}void apply(int p, function<void(T &)> g) {shift(p);g(a[p]);while(p > 1) {p /= 2;a[p] = f(a[2 * p], a[2 * p + 1]);}}T fold_ID(int l, int r) {assert(ok);assert(inII(l, 0, n)); l += s;assert(inII(r, 0, n)); r += s; r--;T x = e, y = e;while(l <= r) {if(l % 2 == 1) { x = f(x, a[l]); l++; }if(r % 2 == 0) { y = f(a[r], y); r--; }l /= 2;r /= 2;}return f(x, y);}T fold_II(int l, int r) { return fold_ID(l + 0, r + 1); }T fold_CI(int l, int r) { return fold_ID(l + 1, r + 1); }T fold_CD(int l, int r) { return fold_ID(l + 1, r + 0); }const T & operator[](int p) {shift(p);return a[p];}T & ref(int p) {shift(p);ok = false;return a[p];}void update() {dec(i, s) { a[i] = f(a[2 * i], a[2 * i + 1]); }ok = true;}};#define OP(s) [&](auto & A, auto & B) { return s; }#define AP(s) [&](auto & A) { s; }// ----template<LL M> class ModInt {private:LL v;pair<LL, LL> ext_gcd(LL a, LL b) {if(b == 0) { assert(a == 1); return { 1, 0 }; }auto p = ext_gcd(b, a % b);return { p.SE, p.FI - (a / b) * p.SE };}public:ModInt(LL vv = 0) { v = vv; if(abs(v) >= M) { v %= M; } if(v < 0) { v += M; } }LL get_v() { return v; }ModInt inv() { return ext_gcd(M, v).SE; }ModInt exp(LL b) {ModInt p = 1, a = v; if(b < 0) { a = a.inv(); b = -b; }while(b) { if(b & 1) { p *= a; } a *= a; b >>= 1; }return p;}friend bool operator< (ModInt a, ModInt b) { return (a.v < b.v); }friend bool operator> (ModInt a, ModInt b) { return (a.v > b.v); }friend bool operator<=(ModInt a, ModInt b) { return (a.v <= b.v); }friend bool operator>=(ModInt a, ModInt b) { return (a.v >= b.v); }friend bool operator==(ModInt a, ModInt b) { return (a.v == b.v); }friend bool operator!=(ModInt a, ModInt b) { return (a.v != b.v); }friend ModInt operator+ (ModInt a ) { return ModInt(+a.v); }friend ModInt operator- (ModInt a ) { return ModInt(-a.v); }friend ModInt operator+ (ModInt a, ModInt b) { return ModInt(a.v + b.v); }friend ModInt operator- (ModInt a, ModInt b) { return ModInt(a.v - b.v); }friend ModInt operator* (ModInt a, ModInt b) { return ModInt(a.v * b.v); }friend ModInt operator/ (ModInt a, ModInt b) { return a * b.inv(); }friend ModInt operator^ (ModInt a, LL b) { return a.exp(b); }friend ModInt & operator+=(ModInt & a, ModInt b) { return (a = a + b); }friend ModInt & operator-=(ModInt & a, ModInt b) { return (a = a - b); }friend ModInt & operator*=(ModInt & a, ModInt b) { return (a = a * b); }friend ModInt & operator/=(ModInt & a, ModInt b) { return (a = a / b); }friend ModInt & operator^=(ModInt & a, LL b) { return (a = a ^ b); }friend istream & operator>>(istream & s, ModInt & b) { s >> b.v; b = ModInt(b.v); return s; }friend ostream & operator<<(ostream & s, ModInt b) { return (s << b.v); }};// ----using MI = ModInt< 1'000'000'007 >;#define PAIR_COMP(f, a, b, c, d) \template<typename F, typename S> struct f { \bool operator() (pair<F, S> x, pair<F, S> y) { return (x.a c y.a) || (x.a == y.a && x.b d y.b); } \}PAIR_COMP(FLSL, FI, SE, <, <);PAIR_COMP(FLSG, FI, SE, <, >);PAIR_COMP(FGSL, FI, SE, >, <);PAIR_COMP(FGSG, FI, SE, >, >);PAIR_COMP(SLFL, SE, FI, <, <);PAIR_COMP(SLFG, SE, FI, <, >);PAIR_COMP(SGFL, SE, FI, >, <);PAIR_COMP(SGFG, SE, FI, >, >);int main() {IN(int, n);vector<pair<int, int>> a(n);inc(i, n) {cin >> a[i].FI;a[i].SE = i;}int INF = 1'000'000'001;a.EB(INF, n);sort(ALL(a), FLSG<int, int>());auto f = [](auto a, auto b) -> pair<int, MI> {if(a.FI != b.FI) { return max(a, b); }else { return { a.FI, a.SE + b.SE }; }};SegmentTree<pair<int, MI>> st(n + 1, f, { 0, 0 });inc(i, n + 1) {int p = a[i].SE;auto v = st.fold_ID(0, p);if(v.FI == 0) { v.SE = 1; }v.FI++;st.apply(p, AP(A = v));}OUT(st[n].SE);}