結果
| 問題 | No.3452 Divide Permutation |
| コンテスト | |
| ユーザー |
momoyuu
|
| 提出日時 | 2026-05-12 18:36:08 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 7,892 bytes |
| 記録 | |
| コンパイル時間 | 1,969 ms |
| コンパイル使用メモリ | 217,620 KB |
| 実行使用メモリ | 56,956 KB |
| 最終ジャッジ日時 | 2026-05-12 18:37:06 |
| 合計ジャッジ時間 | 56,745 ms |
|
ジャッジサーバーID (参考情報) |
judge2_1 / judge1_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | WA * 1 |
| other | AC * 6 WA * 63 |
ソースコード
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
using ll = long long;
#include<set>
#include<atcoder/segtree>
#include<atcoder/modint>
#include<cassert>
using mint = atcoder::modint998244353;
using dat1 = pair<pair<mint,mint>,pair<int,int>>;
dat1 op1(dat1 a,dat1 b) {
dat1 now;
now.first.first = a.first.first * b.first.second + b.first.first;
now.first.second = a.first.second * b.first.second;
return now;
}
dat1 e1(){
return make_pair(make_pair(0, 1), make_pair(-1, -1));
}
using dat2 = int;
dat2 op2(dat2 a,dat2 b) {
return min(a,b);
}
dat2 e2() {
return 1e9;
}
using dat3 = int;
dat3 op3(dat3 a,dat3 b){
return max(a,b);
}
dat3 e3(){
return -1;
}
int fuse = 0;
int f1(dat3 a) {
return a < fuse;
}
void solve(){
int n;
cin>>n;
vector<int> p(n);
for(int i = 0;i<n;i++) cin>>p[i];
for(int i = 0;i<n;i++) p[i]--;
vector<int> idx(n);
for(int i = 0;i<n;i++) {
idx[p[i]] = i;
}
atcoder::segtree<dat1, op1, e1> seg1(n);
// 数字の index
set<int> use;
// 場所の index
set<int> cutuse;
atcoder::segtree<dat2, op2, e2> pmin(p);
atcoder::segtree<dat3, op3, e3> pmax(p);
atcoder::segtree<dat1, op1, e1> psum(n);
atcoder::segtree<dat3, op3, e3> usemax(n);
atcoder::segtree<dat2, op2, e2> usemin(n);
for(int i = 0;i<n;i++) {
psum.set(i, make_pair(make_pair(p[i] + 1, 10),make_pair(i, i)));
}
atcoder::segtree<dat2, op2, e2> can(n);
atcoder::segtree<dat2, op2, e2> notuse(n);
for(int i = 0;i<n;i++) notuse.set(i, i);
vector<int> ok(n, 0);
atcoder::segtree<dat3, op3, e3> conmax(n);
vector<int> mcan(n);
auto judge = [&](int i) {
// cout<<"j1"<<endl;
int mx = conmax.get(i);
int ni = usemin.prod(i + 1, n);
if(ni>mx) {
// cout<<"j2"<<endl;
return;
}
can.set(i, i);
int l = seg1.get(i).second.first;
int r = seg1.get(i).second.second + 1;
assert(0<=l&&l<=r&&r<=n);
assert(pmax.prod(l, r) > ni);
while(r-l>1) {
int m = (l+r)/2;
int mx = pmax.prod(l, m);
if(ni<mx) r = m;
else l = m;
}
mcan[i] = l;
// cout<<"j2"<<endl;
};
auto add = [&](dat1 now,int i) {
use.insert(i);
notuse.set(i, e2());
cutuse.insert(now.second.first);
usemax.set(idx[i], idx[i]);
usemin.set(i, i);
ok[i] = 1;
seg1.set(i, now);
conmax.set(i, pmax.prod(now.second.first, now.second.second+1));
judge(i);
auto itr = use.upper_bound(i);
if(itr!=use.end()) {
int ni = *itr;
can.set(ni,e2());
judge(ni);
}
};
auto erase = [&](int i) {
auto ee = seg1.get(i);
use.erase(i);
notuse.set(i, i);
cutuse.erase(ee.second.first);
ok[i] = 0;
conmax.set(i, e3());
seg1.set(i, e1());
usemin.set(i, e2());
usemax.set(idx[i], e3());
can.set(i, e2());
auto itr = use.upper_bound(i);
if(itr!=use.end()) {
int ni = *itr;
can.set(ni, e2());
judge(ni);
}
};
for(int i = 0;i<n;i++){
if(p[i]==i) {
dat1 now;
now.first.first = p[i] + 1;
now.first.second = 10;
now.second.first = i;
now.second.second = i;
add(now, i);
continue;
}
int ni = p[i];
dat1 now;
now.first.first = 0;
now.first.second = 1;
now.second.first = i;
now.second.second = n - 1;
for(int j = i;j<n;j++){
now.first.first *= 10;
now.first.first += p[j] + 1;
now.first.second *= 10;
}
add(now, ni);
break;
}
vector<mint> ans(n+1);
int last = 0;
vector<pair<pair<int,int>,dat1>> rr;
auto cut = [&](int i) {
assert(i!=0);
auto itr = cutuse.lower_bound(i);
int r = n;
if(itr!=cutuse.end()) r = *itr;
assert(itr!=cutuse.begin());
itr--;
int l = *itr;
int nl = p[l];
dat1 nnl = seg1.get(nl);
rr.push_back(make_pair(make_pair(nl, 0), nnl));
dat1 newl = nnl;
newl.second.second = i - 1;
newl.first = psum.prod(l, i).first;
add(newl, nl);
rr.push_back(make_pair(make_pair(nl, 1), newl));
dat1 newi;
newi.second.first = i;
newi.second.second = r - 1;
newi.first = psum.prod(i, r).first;
add(newi, p[i]);
rr.push_back(make_pair(make_pair(p[i], 1), newi));
};
ans[0] = seg1.all_prod().first.first;
for(int t = 1;t < n;) {
mint tmp = 0;
if(last==n){
ans[t] = seg1.all_prod().first.first;
t++;
continue;
}
{
int ni = idx[last];
int nj = ni - 1;
if(0<=nj && p[nj] == last - 1) {
cut(ni);
}
}
// assert(last!=n-1);
int ni = last + 1;
int need = 0;
rr.clear();
int pos = n;
if(last-1>=0) pos = idx[last-1] + 1;
if(pos!=n && cutuse.find(pos) == cutuse.end()) need++;
if(cutuse.find(idx[last])==cutuse.end()) need++;
if(need==0){
last++;
continue;
}
if(need==2) {
// cout<<"N"<<endl;
bool fn = false;
while(fn==false){
// mc の 1 個前の component
int mc = can.all_prod();
int mmc = 1e9;
if(0<=mc && mc < n) mmc = mcan[mc];
int mn = notuse.all_prod();
auto itrr = use.upper_bound(mn);
int mm = n;
if(itrr!=use.end()) mm = *itrr;
if(mc < mm) {
auto dd = seg1.get(mc);
int l = dd.second.first;
int r = dd.second.second + 1;
//cout<<mmc<<" "<<l<<" "<<r<<" "<<n<<endl;
// if(pmax.prod(l, r) <= mc) {
// judge(mc);
// continue;
// }
cut(mmc);
// assert(pmax.prod(l,r) > mc);
// while(r-l>1){
// int m = (r+l)/2;
// assert(0<=l&&l<=m&&m<=m);
// if(pmax.prod(l, m) > mc) r = m;
// else l = m;
// }
// assert(r-1!=0);
// cut(r-1);
}else{
int ni = idx[mn];
cut(ni);
}
tmp = seg1.all_prod().first.first;
reverse(rr.begin(),rr.end());
for(auto e:rr){
if(e.first.second==1) erase(e.first.first);
else add(e.second, e.first.first);
}
fn = true;
}
// cout<<"N1"<<endl;
}
// cout<<t<<" "<<need<<" "<<last<<endl;
if(pos!=n && cutuse.find(pos) == cutuse.end()){
cut(pos);
}else{
int ni = idx[last];
assert(cutuse.find(ni)==cutuse.end());
cut(ni);
}
if(need!=2) {
ans[t] = seg1.all_prod().first.first;
}else{
ans[t] = tmp;
}
t++;
continue;
}
for(int i = 0;i<n;i++){
cout<<ans[i].val();
if(i!=n-1) cout<<" ";
else cout<<endl;
}
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
solve();
}
}
momoyuu