結果

問題 No.1804 Intersection of LIS
ユーザー ecottea
提出日時 2024-05-19 16:41:23
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 20,992 bytes
コンパイル時間 5,775 ms
コンパイル使用メモリ 295,412 KB
最終ジャッジ日時 2025-02-21 15:59:19
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2 WA * 1
other MLE * 1 -- * 36
権限があれば一括ダウンロードができます

ソースコード

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

#ifndef HIDDEN_IN_VS //
//
#define _CRT_SECURE_NO_WARNINGS
//
#include <bits/stdc++.h>
using namespace std;
//
using ll = long long; using ull = unsigned long long; // -2^63 2^63 = 9 * 10^18int -2^31 2^31 = 2 * 10^9
using pii = pair<int, int>; using pll = pair<ll, ll>; using pil = pair<int, ll>; using pli = pair<ll, int>;
using vi = vector<int>; using vvi = vector<vi>; using vvvi = vector<vvi>; using vvvvi = vector<vvvi>;
using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>; using vvvvl = vector<vvvl>;
using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>;
using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>;
using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>;
template <class T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
using Graph = vvi;
//
const double PI = acos(-1);
int DX[4] = {1, 0, -1, 0}; // 4
int DY[4] = {0, 1, 0, -1};
int INF = 1001001001; ll INFL = 4004004003094073385LL; // (int)INFL = INF, (int)(-INFL) = -INF;
//
struct fast_io { fast_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } fastIOtmp;
//
#define all(a) (a).begin(), (a).end()
#define sz(x) ((int)(x).size())
#define lbpos(a, x) (int)distance((a).begin(), std::lower_bound(all(a), x))
#define ubpos(a, x) (int)distance((a).begin(), std::upper_bound(all(a), x))
#define Yes(b) {cout << ((b) ? "Yes\n" : "No\n");}
#define rep(i, n) for(int i = 0, i##_len = int(n); i < i##_len; ++i) // 0 n-1
#define repi(i, s, t) for(int i = int(s), i##_end = int(t); i <= i##_end; ++i) // s t
#define repir(i, s, t) for(int i = int(s), i##_end = int(t); i >= i##_end; --i) // s t
#define repe(v, a) for(const auto& v : (a)) // a
#define repea(v, a) for(auto& v : (a)) // a
#define repb(set, d) for(int set = 0, set##_ub = 1 << int(d); set < set##_ub; ++set) // d
#define repis(i, set) for(int i = lsb(set), bset##i = set; i >= 0; bset##i -= 1 << i, i = lsb(bset##i)) // set
#define repp(a) sort(all(a)); for(bool a##_perm = true; a##_perm; a##_perm = next_permutation(all(a))) // a
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} //
#define EXIT(a) {cout << (a) << endl; exit(0);} //
#define inQ(x, y, u, l, d, r) ((u) <= (x) && (l) <= (y) && (x) < (d) && (y) < (r)) //
//
template <class T> inline ll powi(T n, int k) { ll v = 1; rep(i, k) v *= n; return v; }
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // true
    
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // true
    
template <class T> inline T getb(T set, int i) { return (set >> i) & T(1); }
template <class T> inline T smod(T n, T m) { n %= m; if (n < 0) n += m; return n; } // mod
//
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repea(x, v) is >> x; return is; }
template <class T> inline vector<T>& operator--(vector<T>& v) { repea(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repea(x, v) ++x; return v; }
#endif //
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#ifdef _MSC_VER
#include "localACL.hpp"
#endif
//using mint = modint1000000007;
using mint = modint998244353;
//using mint = modint; // mint::set_mod(m);
namespace atcoder {
inline istream& operator>>(istream& is, mint& x) { ll x_; is >> x_; x = x_; return is; }
inline ostream& operator<<(ostream& os, const mint& x) { os << x.val(); return os; }
}
using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>; using vvvvm = vector<vvvm>; using pim = pair<int, mint>;
#endif
#ifdef _MSC_VER // Visual Studio
#include "local.hpp"
#else // gcc
inline int popcount(int n) { return __builtin_popcount(n); }
inline int popcount(ll n) { return __builtin_popcountll(n); }
inline int lsb(int n) { return n != 0 ? __builtin_ctz(n) : -1; }
inline int lsb(ll n) { return n != 0 ? __builtin_ctzll(n) : -1; }
template <size_t N> inline int lsb(const bitset<N>& b) { return b._Find_first(); }
inline int msb(int n) { return n != 0 ? (31 - __builtin_clz(n)) : -1; }
inline int msb(ll n) { return n != 0 ? (63 - __builtin_clzll(n)) : -1; }
#define dump(...)
#define dumpel(v)
#define dump_list(v)
#define dump_mat(v)
#define input_from_file(f)
#define output_to_file(f)
#define Assert(b) { if (!(b)) { vc MLE(1<<30); EXIT(MLE.back()); } } // RE MLE
#endif
//O(n log n)
/*
* a[0..n) lis
*
* DP
*/
pii op_lis(pii a, pii b) { return max(a, b); }
pii e_lis() { return { 0, -1 }; } // max -INF 0
template <class T>
dsu LIS_val_to_length(const vector<T>& a, vi* lis = nullptr) {
// verify : https://judge.yosupo.jp/problem/longest_increasing_subsequence
int n = sz(a);
// a b
vector<T> a_uniqed(a); uniq(a_uniqed); int m = sz(a_uniqed);
vi b(n); rep(i, n) b[i] = lbpos(a_uniqed, a[i]);
// dp_i[j] : b[0..i] j
segtree<pii, op_lis, e_lis> dp(m);
// prv[j] : b[i] 1 DP
// DP DP
vi prv(n, -1);
//b[0..5) = [3, 1, 2, 2, 0]
// dp_0[0..3) = [0, 0, 0, 0]
// dp_1[0..3) = [0, 0, 0, 1] (max(0, 0, 0) + 1 = 1)
// dp_2[0..3) = [0, 1, 0, 1] (max(0) + 1 = 1)
// dp_3[0..3) = [0, 1, 2, 1] (max(0, 1) + 1 = 2)
// dp_4[0..3) = [0, 1, 2, 1] (max(0, 1) + 1 = 2)
// dp_5[0..3) = [1, 1, 2, 1] (max() + 1 = 1)
dsu d(n);
// j = b[i]
rep(i, n) {
dump("--- i:", i, "---");
int j = b[i];
// j j
// 1
auto [len, pos] = dp.prod(0, j);
dump(" len, pos:", len, pos);
len++;
// j
// dp[j] O(log n)
// dp
auto [plen, ppos] = dp.get(j);
dump("plen, ppos:", plen, ppos);
if (plen == len) {
if (ppos != -1) d.merge(i, ppos);
dp.set(j, { len, i });
prv[i] = pos;
}
if (len > plen) {
dp.set(j, { len, i });
prv[i] = pos;
}
dump(dp);
}
dump(prv);
//
auto [len, pos] = dp.prod(0, m);
// DP
if (lis != nullptr) {
lis->clear();
while (pos != -1) {
lis->emplace_back(pos);
pos = prv[pos];
}
reverse(all(*lis));
}
return d;
}
/*
1
------------------------------
8
1 1 1 1 2 2 2 2
-1 -1 -1 -1 0 -1 -1 -1
*/
void WA() {
int n;
cin >> n;
vi a(n);
cin >> a;
vi lis;
auto d = LIS_val_to_length(a, &lis);
dump(lis); dump(d);
vi ok(n);
repe(i, lis) ok[d.leader(i)] = 1;
vi res;
rep(i, n) {
if (ok[d.leader(i)]) {
res.push_back(i + 1);
}
}
int K = sz(res);
rep(k, K) cout << res[k] << " \n"[k == K - 1];
}
//
/*
* to :
* cost :
*/
struct WEdge {
// verify : https://judge.yosupo.jp/problem/shortest_path
int to; //
ll cost; //
WEdge() : to(-1), cost(-INFL) {}
WEdge(int to, ll cost) : to(to), cost(cost) {}
//
operator int() const { return to; }
#ifdef _MSC_VER
friend ostream& operator<<(ostream& os, const WEdge& e) {
os << '(' << e.to << ',' << e.cost << ')';
return os;
}
#endif
};
//
/*
* WGraph g
* g[v] : v
*
* verify : https://judge.yosupo.jp/problem/shortest_path
*/
using WGraph = vector<vector<WEdge>>;
// DAG O(n log n)
/*
* DAG G = (V, E) V = [0..n)E
* i→j ⇔ x[i] < x[j] y[i] < y[j]
* G DAG [0..n) G
*/
template <class T>
Graph lattice_DAG_compression(const vector<T>& x, const vector<T>& y) {
// verify : https://atcoder.jp/contests/arc165/tasks/arc165_f
int n = sz(x);
map<T, vi> x_to_is;
rep(i, n) x_to_is[x[i]].emplace_back(i);
vvi k_to_is;
repea(tmp, x_to_is) k_to_is.emplace_back(move(tmp.second));
int K = sz(k_to_is);
Graph g(n); int id = n;
function<void(int, int)> rf = [&](int l, int r) {
if (r - l == 1) return;
int m = (l + r) / 2;
vector<tuple<T, int, int>> yik;
repi(k, l, m - 1) repe(i, k_to_is[k]) yik.emplace_back(2 * y[i] + 1, i, k);
repi(k, m, r - 1) repe(i, k_to_is[k]) yik.emplace_back(2 * y[i], i, k);
sort(all(yik));
int pid = -1;
for (auto& [y, i, k] : yik) {
g.push_back(vi());
if (pid != -1) g[pid].push_back(id);
pid = id;
if (k < m) g[i].push_back(id);
else g[id].push_back(i);
id++;
}
rf(l, m);
rf(m, r);
};
rf(0, K);
return g;
}
//O(n + m)
/*
* i w[i] DAG g 0
*
*/
vl highest_score_path(const Graph& g, const vl& w) {
int n = sz(g);
// sc[s] : s
vl sc(n, 0); vb seen(n);
// DP
function<ll(int)> dfs = [&](int s) {
if (seen[s]) return sc[s];
seen[s] = true;
// s → t
repe(t, g[s]) chmax(sc[s], dfs(t));
sc[s] += w[s];
return sc[s];
};
// s
rep(s, n) dfs(s);
return sc;
}
//O(n + m)
/*
* g
*/
Graph reverse_graph(const Graph& g) {
// verify : https://atcoder.jp/contests/nikkei2019-qual/tasks/nikkei2019_qual_d
int n = sz(g);
Graph g_rev(n);
rep(s, n) repe(t, g[s]) g_rev[t].push_back(s);
return g_rev;
}
//
/*
* int from :
* int to :
* int id :
* bool dir :
*/
struct IEdge {
// verify : https://judge.yosupo.jp/problem/cycle_detection_undirected
int from; //
int to; //
int id; //
bool dir; //
IEdge() : from(-1), to(-1), id(-1), dir(true) {}
IEdge(int from, int to, int id, bool dir = true) : from(from), to(to), id(id), dir(dir) {}
//
operator int() const { return to; }
#ifdef _MSC_VER
friend ostream& operator<<(ostream& os, const IEdge& e) {
os << '(' << e.from << "" << e.to << ',' << "id:" << e.id << ',' << (e.dir ? "fwd" : "rev") << ')';
return os;
}
#endif
};
//
/*
* IGraph g
* g[v] : v
*
* verify : https://judge.yosupo.jp/problem/cycle_detection_undirected
*/
using IGraph = vector<vector<IEdge>>;
//lowlink
/*
* Lowlink(IGraph g) : O(n + m)
* g
*
* bool articulation_pointQ(int s) : O(1)
* s
*
*
* vi get_articulation_points() : O(n)
* g
*
* bool bridgeQ(int j) : O(1)
* j
*
*
* vi get_bridges() : O(m)
* g
*
* vvi get_two_edge_connected_components() : O(n + m)
* g
* 1
*
* vvi get_two_vertex_connected_components() : O(n + m)
* g
* 1
* g
*
*
* bool connectedQ(int s, int t) : O(1)
* s, t
*
* bool separated_by_bridgeQ(int s, int j, int t) : O(1)
* s, t j
*/
class Lowlink {
// : https://kntychance.hatenablog.jp/entry/2022/09/16/161858
int n, m;
IGraph g;
// in[s] : DFS s INF
vl in;
// low[s] : s DFS 退 1 t min in[t]
// 退DFS g
vl low;
// in_e[j] : DFS j
// out_e[j] : DFS j
vl in_e, out_e;
// is_ap[s] : s
vb is_ap;
// is_bg[j] : j
vb is_bg;
public:
// g
Lowlink(const IGraph& g) : n(sz(g)), m(-1), g(g), in(n, -1), low(n), is_ap(n) {
// verify : https://atcoder.jp/contests/abc301/tasks/abc301_h
rep(s, n) repe(t, g[s]) chmax(m, t.id);
m++;
in_e.resize(m), out_e.resize(m);
is_bg.assign(m, false);
int rt; //
ll time = 0; //
// DFS
function<void(int, int)> dfs = [&](int s, int id) {
// s
in[s] = low[s] = time++;
int child_cnt = 0; // DFS
repe(t, g[s]) {
//
//
if (t.id == id || t == s) continue;
// t
if (in[t] != -1) {
// s→t 退
// t DFS 辿 v
// in[t] < in[v] low[s] = in[t]
// t→s 退
// s→t DFS
// low[s] ≦ in[s] < in[t]
// chmin 使
chmin(low[s], in[t]);
}
// t
else {
//
in_e[t.id] = time++;
dfs(t, t.id);
out_e[t.id] = time++;
// s→t DFS low[t] low[s]
chmin(low[s], low[t]);
// s→t DFS s s-t
if (in[s] < low[t]) is_bg[t.id] = true;
// t DFS s s t
// s
is_ap[s] = is_ap[s] || (in[s] <= low[t]);
child_cnt++;
}
}
// s 2
if (s == rt) is_ap[s] = (child_cnt >= 2);
};
// DFS in  low
rep(s, n) {
if (in[s] != -1) continue;
// INF
time = (time / INF + 1) * INF;
// s DFS in low
rt = s;
dfs(s, -1);
}
}
// s
bool articulation_pointQ(int s) {
return is_ap[s];
}
// g
vi get_articulation_points() {
// verify : https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_3_A
vi aps;
rep(s, n) if (is_ap[s]) aps.push_back(s);
return aps;
}
// j
bool bridgeQ(int j) {
return is_bg[j];
}
// g
vi get_bridges() {
// verify : https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_3_B
vi bgs;
rep(j, m) if (is_bg[j]) bgs.push_back(j);
return bgs;
}
// g
vvi get_two_edge_connected_components() {
// verify : https://judge.yosupo.jp/problem/two_edge_connected_components
// ccs :
vvi ccs; vb seen(n);
function<void(int, int)> dfs = [&](int s, int p) {
ccs.back().push_back(s);
seen[s] = true;
repe(t, g[s]) {
//
if (t == p || seen[t] || is_bg[t.id]) continue;
dfs(t, s);
}
};
rep(s, n) {
if (seen[s]) continue;
ccs.push_back(vi());
dfs(s, -1);
}
return ccs;
}
// g
vvi get_two_vertex_connected_components() {
// verify : https://judge.yosupo.jp/problem/biconnected_components
// ccs :
vvi ccs; vb seen(m);
// s :
// ap :
// k :
function<void(int, int, int)> dfs = [&](int s, int ap, int k) {
repe(t, g[s]) {
//
if (seen[t.id]) continue;
seen[t.id] = true;
// s t s-t
if (in[s] <= low[t]) {
ccs.push_back(vi{ t.id });
dfs(t, s, sz(ccs) - 1);
continue;
}
//
ccs[k].push_back(t.id);
// 退
if (in[s] < in[t]) dfs(t, ap, k);
}
};
rep(s, n) repe(t, g[s]) {
if (seen[t.id]) continue;
seen[t.id] = true;
ccs.push_back(vi{ t.id });
dfs(t, s, sz(ccs) - 1);
}
return ccs;
}
bool connectedQ(int s, int t) {
return in[s] / INF == in[t] / INF;
}
bool separated_by_bridgeQ(int s, int j, int t) {
// verify : https://atcoder.jp/contests/abc301/tasks/abc301_h
if (!connectedQ(s, t)) return false;
if (!is_bg[j]) return false;
bool bs = in_e[j] < in[s] && in[s] < out_e[j];
bool bt = in_e[j] < in[t] && in[t] < out_e[j];
return bs != bt;
}
};
int main() {
// input_from_file("input.txt");
// output_to_file("output.txt");
int n;
cin >> n;
vi p(n);
cin >> p;
vi x(n);
iota(all(x), 0);
auto g = lattice_DAG_compression(x, p);
int N = sz(g);
vl w(N);
rep(i, n) w[i] = 1;
auto d = highest_score_path(g, w);
dump(d);
auto gR = reverse_graph(g);
auto dR = highest_score_path(gR, w);
dump(dR);
ll len_max = 0;
rep(i, n) chmax(len_max, d[i]);
dump(len_max);
Graph g2(g);
g2.push_back(vi());
g2.push_back(vi());
rep(i, n) {
if (d[i] == len_max) g2[N].push_back(i);
if (dR[i] == len_max) g2[i].push_back(N + 1);
}
IGraph g3(N + 2); int id = 0;
rep(i, N + 2) repe(j, g2[i]) {
g3[i].push_back({ i, j, id, 1 });
g3[j].push_back({ j, i, id, 0 });
id++;
}
Lowlink G3(g3);
auto arts = G3.get_articulation_points();
while (!arts.empty()) {
if (arts.back() >= n) arts.pop_back();
else break;
}
int K = sz(arts);
cout << K << endl;
rep(k, K) cout << p[arts[k]] << " \n"[k == K - 1];
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0