結果
| 問題 |
No.1720 Division Permutation
|
| コンテスト | |
| ユーザー |
shobonvip
|
| 提出日時 | 2025-03-11 17:06:52 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,561 bytes |
| コンパイル時間 | 4,782 ms |
| コンパイル使用メモリ | 271,076 KB |
| 実行使用メモリ | 31,132 KB |
| 最終ジャッジ日時 | 2025-03-11 17:07:06 |
| 合計ジャッジ時間 | 13,188 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 11 WA * 49 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
#include<atcoder/segtree>
int pt_op(int a, int b) {
return min(a, b);
}
int pt_e() {
return 1e9;
}
struct pt_node {
// typ:
// 0: one
// 1: inc
// 2: dec
// 3: prime
int par, typ, l, r;
};
// assume p in [0, n) with length n
// ref: https://judge.yosupo.jp/submission/252918
vector<pt_node> permutation_tree(vector<int> p) {
struct left_pfix {
int x, mx, mn;
};
int n = (int)p.size();
assert(n >= 1);
vector<int> pinv(n);
for(int i=0; i<n; i++) {
pinv[p[i]] = i;
}
atcoder::segtree<int,pt_op,pt_e> seg(pinv);
vector<left_pfix> st;
vector candi(n+1, vector<pair<int,int>>(0));
for(int r=1; r<=n; r++) {
left_pfix now = {r-1, p[r-1], p[r-1]};
while (!st.empty()) {
st.back().mx = max(st.back().mx, now.mx);
st.back().mn = min(st.back().mn, now.mn);
auto g = st.back();
if (g.mx-g.mn+1 == r-g.x) {
candi[r-g.x].push_back(pair(g.x, r));
now = g;
st.pop_back();
}else if(seg.prod(g.mn,g.mx+1) < g.x){
st.pop_back();
if (st.empty()) continue;
auto& h = st.back();
h.mx = max(h.mx, g.mx);
h.mn = min(h.mn, g.mn);
}else{
break;
}
}
st.push_back(now);
}
vector<pt_node> ret;
vector<int> node_id(n);
vector<int> node_jump(n+1);
for (int i=0; i<n; i++) {
ret.push_back(pt_node{-1, 0, i, i+1});
}
iota(node_id.begin(), node_id.end(), 0);
iota(node_jump.begin(), node_jump.end(), 1);
for (int len=2; len<=n; len++) {
for (auto [l,r]: candi[len]) {
int m = node_jump[l];
if (node_jump[m] == r) {
int a = node_id[l];
int b = node_id[m];
int tmp_typ = p[l] < p[r-1] ? 1 : 2;
if (tmp_typ == ret[a].typ) {
ret[b].par = a;
ret[a].r = r;
}else{
int c = (int)ret.size();
ret.push_back(pt_node{-1, tmp_typ, l, r});
ret[a].par = c;
ret[b].par = c;
node_id[l] = c;
}
node_jump[l] = r;
}else{
int c = (int)ret.size();
ret.push_back(pt_node{-1, 3, l, r});
for (int x=l; x!=r; x=node_jump[x]) {
int a = node_id[x];
ret[a].par = c;
}
node_jump[l] = r;
node_id[l] = c;
}
}
}
return ret;
}
/**
author: shobonvip
created: 2025.03.11 16:51:34
**/
#include<bits/stdc++.h>
using namespace std;
//* ATCODER
#include<atcoder/all>
using namespace atcoder;
typedef modint998244353 mint;
//*/
/* BOOST MULTIPRECISION
#include<boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
//*/
typedef long long ll;
#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)
#define all(v) v.begin(), v.end()
template <typename T> bool chmin(T &a, const T &b) {
if (a <= b) return false;
a = b;
return true;
}
template <typename T> bool chmax(T &a, const T &b) {
if (a >= b) return false;
a = b;
return true;
}
template <typename T> T max(vector<T> &a){
assert(!a.empty());
T ret = a[0];
for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
return ret;
}
template <typename T> T min(vector<T> &a){
assert(!a.empty());
T ret = a[0];
for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
return ret;
}
template <typename T> T sum(vector<T> &a){
T ret = 0;
for (int i=0; i<(int)a.size(); i++) ret += a[i];
return ret;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k; cin >> n >> k;
vector<int> p(n);
rep(i,0,n) {
cin >> p[i];
p[i]--;
}
vector<pt_node> f = permutation_tree(p);
int m = (int)f.size();
int root = -1;
vector ikeru(m, vector<int>(0));
rep(i,0,m) {
if (f[i].par == -1) {
root = i;
}else{
ikeru[f[i].par].push_back(i);
}
}
vector dp(m, vector<mint>(k+1));
auto dfs = [&](auto self, int i) -> void {
sort(all(ikeru[i]), [&](int a, int b) {
return f[a].l < f[b].l;
}) ;
for (int j: ikeru[i]) {
self(self, j);
}
if (f[i].typ == 1 || f[i].typ == 2) {
vector<mint> horyu(k+1);
vector<mint> rui(k+1);
horyu[0] = 1;
dp[i][0] = 1;
for (int j: ikeru[i]) {
vector<mint> ndp(k+1);
rep(x,0,k+1) rep(y,0,k+1-x) {
ndp[x+y] += dp[i][x] * dp[j][y];
}
rep(x,0,k) {
ndp[x+1] += rui[x];
}
rep(x,0,k+1) rui[x] += horyu[x];
horyu = ndp;
swap(dp[i], ndp);
}
}else if(f[i].typ == 3){
dp[i][0] = 1;
for (int j: ikeru[i]) {
vector<mint> ndp(k+1);
rep(x,0,k+1) rep(y,0,k+1-x) {
ndp[x+y] += dp[i][x] * dp[j][y];
}
swap(dp[i], ndp);
}
}else{
dp[i][1] = 1;
}
};
dfs(dfs, root);
rep(i,1,k+1) {
cout << dp[root][i].val() << '\n';
}
}
shobonvip