QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#298917 | #7899. Say Hello to the Future | ucup-team087# | TL | 969ms | 21372kb | C++20 | 26.1kb | 2024-01-06 15:50:32 | 2024-01-06 15:50:33 |
Judging History
answer
#ifndef LOCAL
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
//#define int ll
#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
using pi=pair<int,int>;
using vi=vc<int>;
template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
return os<<"{"<<p.a<<","<<p.b<<"}";
}
template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
os<<"{";
for(auto e:v)os<<e<<",";
return os<<"}";
}
#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
os<<t<<" ";
dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif
using uint=unsigned;
using ull=unsigned long long;
template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
return os<<vc<t>(all(a));
}
template<int i,class T>
void print_tuple(ostream&,const T&){
}
template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
if(i)os<<",";
os<<get<i>(t);
print_tuple<i+1,T,Args...>(os,t);
}
template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
os<<"{";
print_tuple<0,tuple<Args...>,Args...>(os,t);
return os<<"}";
}
ll read(){
ll i;
cin>>i;
return i;
}
vi readvi(int n,int off=0){
vi v(n);
rep(i,n)v[i]=read()+off;
return v;
}
pi readpi(int off=0){
int a,b;cin>>a>>b;
return pi(a+off,b+off);
}
template<class t>
void print_single(t x,int suc=1){
cout<<x;
if(suc==1)
cout<<"\n";
if(suc==2)
cout<<" ";
}
template<class t,class u>
void print_single(const pair<t,u>&p,int suc=1){
print_single(p.a,2);
print_single(p.b,suc);
}
template<class T>
void print_single(const vector<T>&v,int suc=1){
rep(i,v.size())
print_single(v[i],i==int(v.size())-1?suc:2);
}
template<class T>
void print_offset(const vector<T>&v,ll off,int suc=1){
rep(i,v.size())
print_single(v[i]+off,i==int(v.size())-1?suc:2);
}
template<class T,size_t N>
void print_single(const array<T,N>&v,int suc=1){
rep(i,N)
print_single(v[i],i==int(N)-1?suc:2);
}
template<class T>
void print(const T&t){
print_single(t);
}
template<class T,class ...Args>
void print(const T&t,const Args&...args){
print_single(t,2);
print(args...);
}
string readString(){
string s;
cin>>s;
return s;
}
template<class T>
T sq(const T& t){
return t*t;
}
void YES(bool ex=true){
cout<<"YES\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void NO(bool ex=true){
cout<<"NO\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void Yes(bool ex=true){
cout<<"Yes\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void No(bool ex=true){
cout<<"No\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
//#define CAPITAL
/*
void yes(bool ex=true){
#ifdef CAPITAL
cout<<"YES"<<"\n";
#else
cout<<"Yes"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void no(bool ex=true){
#ifdef CAPITAL
cout<<"NO"<<"\n";
#else
cout<<"No"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}*/
void possible(bool ex=true){
#ifdef CAPITAL
cout<<"POSSIBLE"<<"\n";
#else
cout<<"Possible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void impossible(bool ex=true){
#ifdef CAPITAL
cout<<"IMPOSSIBLE"<<"\n";
#else
cout<<"Impossible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
constexpr ll ten(int n){
return n==0?1:ten(n-1)*10;
}
const ll infLL=LLONG_MAX/3;
#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif
int topbit(signed t){
return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
return t==0?-1:63-__builtin_clzll(t);
}
int topbit(ull t){
return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
return a==0?64:__builtin_ctzll(a);
}
int botbit(ull a){
return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
return __builtin_popcount(t);
}
int popcount(ll t){
return __builtin_popcountll(t);
}
int popcount(ull t){
return __builtin_popcountll(t);
}
int bitparity(ll t){
return __builtin_parityll(t);
}
bool ispow2(int i){
return i&&(i&-i)==i;
}
ll mask(int i){
return (ll(1)<<i)-1;
}
ull umask(int i){
return (ull(1)<<i)-1;
}
ll minp2(ll n){
if(n<=1)return 1;
else return ll(1)<<(topbit(n-1)+1);
}
bool inc(int a,int b,int c){
return a<=b&&b<=c;
}
template<class t> void mkuni(vc<t>&v){
sort(all(v));
v.erase(unique(all(v)),v.ed);
}
ll rand_int(ll l, ll r) { //[l, r]
//#ifdef LOCAL
static mt19937_64 gen;
/*#else
static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
#endif*/
return uniform_int_distribution<ll>(l, r)(gen);
}
ll rand_int(ll k){ //[0,k)
return rand_int(0,k-1);
}
template<class t>
void myshuffle(vc<t>&a){
rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}
template<class t,class u>
int lwb(const vc<t>&v,const u&a){
return lower_bound(all(v),a)-v.bg;
}
template<class t,class u>
bool bis(const vc<t>&v,const u&a){
return binary_search(all(v),a);
}
vvc<int> readGraph(int n,int m){
vvc<int> g(n);
rep(i,m){
int a,b;
cin>>a>>b;
//sc.read(a,b);
a--;b--;
g[a].pb(b);
g[b].pb(a);
}
return g;
}
vvc<int> readTree(int n){
return readGraph(n,n-1);
}
template<class t>
vc<t> presum(const vc<t>&a){
vc<t> s(si(a)+1);
rep(i,si(a))s[i+1]=s[i]+a[i];
return s;
}
vc<ll> presum(const vi&a){
vc<ll> s(si(a)+1);
rep(i,si(a))s[i+1]=s[i]+a[i];
return s;
}
//BIT で数列を管理するときに使う (CF850C)
template<class t>
vc<t> predif(vc<t> a){
gnr(i,1,si(a))a[i]-=a[i-1];
return a;
}
template<class t>
vvc<ll> imos(const vvc<t>&a){
int n=si(a),m=si(a[0]);
vvc<ll> b(n+1,vc<ll>(m+1));
rep(i,n)rep(j,m)
b[i+1][j+1]=b[i+1][j]+b[i][j+1]-b[i][j]+a[i][j];
return b;
}
//verify してないや
void transvvc(int&n,int&m){
swap(n,m);
}
template<class t,class... Args>
void transvvc(int&n,int&m,vvc<t>&a,Args&...args){
assert(si(a)==n);
vvc<t> b(m,vi(n));
rep(i,n){
assert(si(a[i])==m);
rep(j,m)b[j][i]=a[i][j];
}
a.swap(b);
transvvc(n,m,args...);
}
//CF854E
void rotvvc(int&n,int&m){
swap(n,m);
}
template<class t,class... Args>
void rotvvc(int&n,int&m,vvc<t>&a,Args&...args){
assert(si(a)==n);
vvc<t> b(m,vi(n));
rep(i,n){
assert(si(a[i])==m);
rep(j,m)b[m-1-j][i]=a[i][j];
}
a.swap(b);
rotvvc(n,m,args...);
}
//ソートして i 番目が idx[i]
//CF850C
template<class t>
vi sortidx(const vc<t>&a){
int n=si(a);
vi idx(n);iota(all(idx),0);
sort(all(idx),[&](int i,int j){return a[i]<a[j];});
return idx;
}
//vs[i]=a[idx[i]]
//例えば sortidx で得た idx を使えば単にソート列になって返ってくる
//CF850C
template<class t>
vc<t> a_idx(const vc<t>&a,const vi&idx){
int n=si(a);
assert(si(idx)==n);
vc<t> vs(n);
rep(i,n)vs[i]=a[idx[i]];
return vs;
}
//CF850C
vi invperm(const vi&p){
int n=si(p);
vi q(n);
rep(i,n)q[p[i]]=i;
return q;
}
template<class t,class s=t>
s SUM(const vc<t>&a){
return accumulate(all(a),s(0));
}
template<class t,size_t K,class s=t>
s SUM(const array<t,K>&a){
return accumulate(all(a),s(0));
}
template<class t>
t MAX(const vc<t>&a){
return *max_element(all(a));
}
template<class t>
pair<t,int> MAXi(const vc<t>&a){
auto itr=max_element(all(a));
return mp(*itr,itr-a.bg);
}
template<class A>
auto MIN(const A&a){
return *min_element(all(a));
}
template<class t>
pair<t,int> MINi(const vc<t>&a){
auto itr=min_element(all(a));
return mp(*itr,itr-a.bg);
}
vi vid(int n){
vi res(n);iota(all(res),0);
return res;
}
template<class S>
void soin(S&s){
sort(all(s));
}
template<class S,class F>
void soin(S&s,F&&f){
sort(all(s),forward<F>(f));
}
template<class S>
S soout(S s){
soin(s);
return s;
}
template<class S>
void rein(S&s){
reverse(all(s));
}
template<class S>
S reout(S s){
rein(s);
return s;
}
template<class t,class u>
pair<t,u>&operator+=(pair<t,u>&a,pair<t,u> b){
a.a+=b.a;a.b+=b.b;return a;}
template<class t,class u>
pair<t,u>&operator-=(pair<t,u>&a,pair<t,u> b){
a.a-=b.a;a.b-=b.b;return a;}
template<class t,class u>
pair<t,u> operator+(pair<t,u> a,pair<t,u> b){return mp(a.a+b.a,a.b+b.b);}
template<class t,class u>
pair<t,u> operator-(pair<t,u> a,pair<t,u> b){return mp(a.a-b.a,a.b-b.b);}
template<class t,class u>
pair<t,u> operator-(pair<t,u> a){return mp(-a.a,-a.b);}
template<class t,class u>
istream&operator>>(istream&is,pair<t,u>&a){
return is>>a.a>>a.b;
}
template<class t>
t gpp(vc<t>&vs){
assert(si(vs));
t res=move(vs.back());
vs.pop_back();
return res;
}
template<class t,class u>
void pb(vc<t>&a,const vc<u>&b){
a.insert(a.ed,all(b));
}
template<class t,class...Args>
vc<t> cat(vc<t> a,Args&&...b){
(pb(a,forward<Args>(b)),...);
return a;
}
template<class t,class u>
vc<t>& operator+=(vc<t>&a,u x){
for(auto&v:a)v+=x;
return a;
}
template<class t,class u>
vc<t> operator+(vc<t> a,u x){
return a+=x;
}
template<class t>
vc<t> operator+(const vc<t>&a,const vc<t>&b){
vc<t> c(max(si(a),si(b)));
rep(i,si(a))c[i]+=a[i];
rep(i,si(b))c[i]+=b[i];
return c;
}
template<class t,class u>
vc<t>& operator-=(vc<t>&a,u x){
for(auto&v:a)v-=x;
return a;
}
template<class t,class u>
vc<t>& operator-(vc<t> a,u x){
return a-=x;
}
template<class t,class u>
void remval(vc<t>&a,const u&v){
a.erase(remove(all(a),v),a.ed);
}
//消した要素の個数を返してくれる
//UCUP 2-8-F
template<class t,class F>
int remif(vc<t>&a,F f){
auto itr=remove_if(all(a),f);
int res=a.ed-itr;
a.erase(itr,a.ed);
return res;
}
template<class VS,class u>
void fila(VS&vs,const u&a){
fill(all(vs),a);
}
template<class t,class u>
int findid(const vc<t>&vs,const u&a){
auto itr=find(all(vs),a);
if(itr==vs.ed)return -1;
else return itr-vs.bg;
}
template<class t>
void rtt(vc<t>&vs,int i){
rotate(vs.bg,vs.bg+i,vs.ed);
}
//N() が単位元
//VERIFY: yosupo
//CF407E
template<class N>
struct segtree{
vc<N> x;
int n,s;
segtree(){}
template<class t>
segtree(const vc<t>&a){
n=a.size();
s=1;
while(s<n){s*=2;}
x.resize(s*2);
rep(i,n)
x[s+i]=N(a[i]);
gnr(i,1,s)
x[i]=N::merge(x[i*2],x[i*2+1]);
}
//NOT Verified
segtree(int nn){
resize(nn);
}
void resize(int nn){
n=nn;
s=1;
while(s<n){s*=2;}
x.assign(s*2,N());
gnr(i,1,s)
x[i]=N::merge(x[i*2],x[i*2+1]);
}
template<class t>
void load(const vc<t>&a){
n=a.size();
s=1;
while(s<n){s*=2;}
x.resize(s*2);
rep(i,n)
x[s+i]=N(a[i]);
rng(i,n,s)
x[s+i]=N();
gnr(i,1,s)
x[i]=N::merge(x[i*2],x[i*2+1]);
}
void clear(){
rep(i,n)
x[s+i]=N();
gnr(i,1,s)
x[i]=N::merge(x[i*2],x[i*2+1]);
}
N point_get(int i){
assert(inc(0,i,n-1));
return x[i+s];
}
void point_set(int i,const N&t){
assert(inc(0,i,n-1));
i+=s;
x[i]=t;
while(i>>=1)x[i]=N::merge(x[i*2],x[i*2+1]);
}
void point_merge(int i,const N&t){
assert(inc(0,i,n-1));
i+=s;
x[i]=N::merge(x[i],t);
while(i>>=1)x[i]=N::merge(x[i*2],x[i*2+1]);
}
template<class F,class...Args>
void point_change(int i,F f,Args&&...args){
assert(inc(0,i,n-1));
i+=s;
(x[i].*f)(forward<Args>(args)...);
while(i>>=1)x[i]=N::merge(x[i*2],x[i*2+1]);
}
N composite(int b,int e){
assert(0<=b&&b<=e&&e<=n);
N lf,rt;
for(int l=b+s,r=e+s;l<r;l>>=1,r>>=1){
if (l&1){
lf=N::merge(lf,x[l]);
l++;
}
if (r&1){
r--;
rt=N::merge(x[r],rt);
}
}
return N::merge(lf,rt);
}
N getall(){
return x[1];
}
//UTPC2020E
//n 超えるかもしれない
template <class F,class... Args>
pair<int,N> max_right(int l,F f,Args&&... args){
assert((N().*f)(forward<Args>(args)...));
assert(0<=l&&l<=n);
if(l==n)return mp(n,N());
l+=s;
N sm;
assert((sm.*f)(forward<Args>(args)...));
do {
while (l % 2 == 0) l >>= 1;
if (!(N::merge(sm,x[l]).*f)(forward<Args>(args)...)){
while (l < s) {
l = (2 * l);
N tmp=N::merge(sm,x[l]);
if ((tmp.*f)(forward<Args>(args)...)) {
sm = tmp;
l++;
}
}
return mp(l - s,sm);
}
sm = N::merge(sm, x[l]);
l++;
} while ((l & -l) != l);
return mp(n,sm);
}
//UTPC2020E
template <class F,class... Args>
pair<int,N> min_left(int r,F f,Args&&... args){
assert((N().*f)(forward<Args>(args)...));
assert(0<=r&&r<=n);
if(r==0)return mp(0,N());
r+=s;
N sm;
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!(N::merge(x[r],sm).*f)(forward<Args>(args)...)) {
while (r < s) {
r = (2 * r + 1);
N tmp=N::merge(x[r],sm);
if ((tmp.*f)(forward<Args>(args)...)) {
sm = tmp;
r--;
}
}
return mp(r + 1 - s,sm);
}
sm = N::merge(x[r], sm);
} while ((r & -r) != r);
return mp(0,sm);
}
//行列とか乗せて必要なのはベクトルとの積,みたいなときに使える?
//CF Goodbye 2016 E
//CF 896 F
template<class F,class T,class... Args>
T accumulate(int l,int r,F f,T t,Args&&... args) {
assert(0<=l&&l<=r&&r<=n);
static int buf[2][30];
int cnt[2]{};
for(l+=s,r+=s;l<r;l>>=1,r>>=1){
if(l&1)buf[0][cnt[0]++]=l;
if(r&1)buf[1][cnt[1]++]=r-1;
l++;
}
rep(i,cnt[0])t=(x[buf[0][i]].*f)(t,forward<Args>(args)...);
per(i,cnt[1])t=(x[buf[1][i]].*f)(t,forward<Args>(args)...);
return t;
}
};
//atcoder-library をまあまあコピーして使っている
//N() が単位元
//merge で片方が inactive のときはもう片方をそのまま返す,
//といったときに,lazy の情報までコピーして渡さないようにする
//クエリできる点が[0,s)だったのを[0,n)に変えた (UCUP1-21D)
//ch,max_rightは動くと思う
//ちゃんと test してないから assert とかが壊れたらごめん
//VERIFY:
//https://atcoder.jp/contests/practice2/tasks/practice2_k
template<class N,bool Beats=false>
struct seglazy{
vc<N> x;
int n,L,s;
seglazy(){}
template<class T>
seglazy(const vc<T>& a){
n=a.size();
L=0;
while((1<<L)<n)L++;
s=1<<L;
x.resize(s*2);
rep(i,n)x[s+i]=N(a[i]);
gnr(i,1,s)upd(i);
}
seglazy(int nn){
n=nn;
L=0;
while((1<<L)<n)L++;
s=1<<L;
x.assign(s*2,N());
gnr(i,1,s)upd(i);
}
void upd(int i){
x[i]=N::merge(x[i*2],x[i*2+1]);
}
void push(int i){
x[i].push(x[i*2],x[i*2+1]);
}
N composite(int l,int r){
assert(0<=l&&l<=r&&r<=n);
if(l==r)return N();
l+=s;
r+=s;
for (int i = L; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
N sml,smr;
while (l < r) {
if (l & 1) sml = N::merge(sml, x[l++]);
if (r & 1) smr = N::merge(x[--r], smr);
l >>= 1;
r >>= 1;
}
return N::merge(sml, smr);
}
//UCUP1-21 D
template<class F,class... Args>
void ch_beats(int i,F f,Args&&... args){
if((x[i].*f)(forward<Args>(args)...))return;
push(i);
ch_beats(i*2,f,forward<Args>(args)...);
ch_beats(i*2+1,f,forward<Args>(args)...);
upd(i);
}
template<class F,class... Args>
void ch(int l, int r, F f,Args&&... args) {
assert(0<=l&&l<=r&&r<=n);
if (l == r) return;
l+=s;
r+=s;
for (int i = L; i >= 1; i--) {
if (((l >> i) << i) != l) push(l >> i);
if (((r >> i) << i) != r) push((r - 1) >> i);
}
static int buf[2][30];
int cnt[2]{};
{
int l2 = l, r2 = r;
while (l < r) {
if (l & 1){
//(x[l++].*f)(forward<Args>(args)...);
buf[0][cnt[0]++]=l++;
}
if (r & 1){
//(x[--r].*f)(forward<Args>(args)...);
buf[1][cnt[1]++]=--r;
}
l >>= 1;
r >>= 1;
}
l = l2;
r = r2;
}
if constexpr(Beats){
rep(i,cnt[0])ch_beats(buf[0][i],f,forward<Args>(args)...);
per(i,cnt[1])ch_beats(buf[1][i],f,forward<Args>(args)...);
}else{
rep(i,cnt[0])(x[buf[0][i]].*f)(forward<Args>(args)...);
per(i,cnt[1])(x[buf[1][i]].*f)(forward<Args>(args)...);
}
for (int i = 1; i <= L; i++) {
if (((l >> i) << i) != l) upd(l >> i);
if (((r >> i) << i) != r) upd((r - 1) >> i);
}
}
template<class F,class... Args>
void chall(F f,Args&&... args){
if constexpr(Beats){
ch_beats(1,f,forward<Args>(args)...);
}else{
(x[1].*f)(forward<Args>(args)...);
}
}
N getall(){return x[1];}
template <class F,class... Args>
pair<int,N> max_right(int l,F f,Args&&... args){
assert(0<=l&&l<=n);
if(l==n)return mp(n,N());
l+=s;
for (int i = L; i >= 1; i--) push(l >> i);
N sm;
assert((sm.*f)(forward<Args>(args)...));
do {
while (l % 2 == 0) l >>= 1;
if (!(N::merge(sm,x[l]).*f)(forward<Args>(args)...)){
while (l < s) {
push(l);
l = (2 * l);
N tmp=N::merge(sm,x[l]);
if ((tmp.*f)(forward<Args>(args)...)) {
sm = tmp;
l++;
}
}
return mp(l - s,sm);
}
sm = N::merge(sm, x[l]);
l++;
} while ((l & -l) != l);
return mp(n,sm);
}
//XXI Opencup Krakow M
template <class F,class... Args>
pair<int,N> min_left(int r,F f,Args&&... args){
assert(0<=r&&r<=n);
if(r==0)return mp(0,N());
r+=s;
for (int i = L; i >= 1; i--) push((r - 1) >> i);
N sm;
do {
r--;
while (r > 1 && (r % 2)) r >>= 1;
if (!(N::merge(x[r],sm).*f)(forward<Args>(args)...)) {
while (r < s) {
push(r);
r = (2 * r + 1);
N tmp=N::merge(x[r],sm);
if ((tmp.*f)(forward<Args>(args)...)) {
sm = tmp;
r--;
}
}
return mp(r + 1 - s,sm);
}
sm = N::merge(x[r], sm);
} while ((r & -r) != r);
return mp(0,sm);
}
template<class F,class...Args>
void point_change(int p,F f,Args&&...args){
assert(0 <= p && p < n);
p += s;
for (int i = L; i >= 1; i--) push(p >> i);
(x[p].*f)(forward<Args>(args)...);
for (int i = 1; i <= L; i++) upd(p >> i);
}
void point_merge(int p,const N&t){
assert(0 <= p && p < n);
p += s;
for (int i = L; i >= 1; i--) push(p >> i);
x[p]=N::merge(x[p],t);
for (int i = 1; i <= L; i++) upd(p >> i);
}
N point_get(int p){
assert(0 <= p && p < n);
p += s;
for (int i = L; i >= 1; i--) push(p >> i);
return x[p];
}
void point_set(int p,N val){
assert(0 <= p && p < n);
p += s;
for (int i = L; i >= 1; i--) push(p >> i);
x[p]=val;
for (int i = 1; i <= L; i++) upd(p >> i);
}
void enumerater(int l,int r,int i,int b,int e,vc<N>&dst){
if(e<=l||r<=b)
return;
if(l+1==r){
dst.pb(x[i]);
return;
}
push(i);
int m=(l+r)/2;
enumerater(l,m,i*2,b,e,dst);
enumerater(m,r,i*2+1,b,e,dst);
}
void enumerate(int b,int e,vc<N>&dst){
assert(0<=b&&b<=e&&e<=n);
return enumerater(0,s,1,b,e,dst);
}
};
//mint107 は verify してねえ
//#define DYNAMIC_MOD
struct modinfo{uint mod,root;
#ifdef DYNAMIC_MOD
constexpr modinfo(uint m,uint r):mod(m),root(r),im(0){set_mod(m);}
ull im;
constexpr void set_mod(uint m){
mod=m;
im=ull(-1)/m+1;
}
uint product(uint a,uint b)const{
ull z=ull(a)*b;
uint x=((unsigned __int128)z*im)>>64;
uint v=uint(z)-x*mod;
return v<mod?v:v+mod;
}
#endif
};
template<modinfo const&ref>
struct modular{
static constexpr uint const &mod=ref.mod;
static modular root(){return modular(ref.root);}
uint v;
//modular(initializer_list<uint>ls):v(*ls.bg){}
modular(ll vv=0){s(vv%mod+mod);}
modular& s(uint vv){
v=vv<mod?vv:vv-mod;
return *this;
}
modular operator-()const{return modular()-*this;}
modular& operator+=(const modular&rhs){return s(v+rhs.v);}
modular&operator-=(const modular&rhs){return s(v+mod-rhs.v);}
modular&operator*=(const modular&rhs){
#ifndef DYNAMIC_MOD
v=ull(v)*rhs.v%mod;
#else
v=ref.product(v,rhs.v);
#endif
return *this;
}
modular&operator/=(const modular&rhs){return *this*=rhs.inv();}
modular operator+(const modular&rhs)const{return modular(*this)+=rhs;}
modular operator-(const modular&rhs)const{return modular(*this)-=rhs;}
modular operator*(const modular&rhs)const{return modular(*this)*=rhs;}
modular operator/(const modular&rhs)const{return modular(*this)/=rhs;}
modular pow(ll n)const{
if(n<0)return inv().pow(-n);
modular res(1),x(*this);
while(n){
if(n&1)res*=x;
x*=x;
n>>=1;
}
return res;
}
modular inv()const{return pow(mod-2);}
/*modular inv()const{
int x,y;
int g=extgcd<ll>(v,mod,x,y);
assert(g==1);
if(x<0)x+=mod;
return modular(x);
}*/
friend modular operator+(ll x,const modular&y){
return modular(x)+y;
}
friend modular operator-(ll x,const modular&y){
return modular(x)-y;
}
friend modular operator*(ll x,const modular&y){
return modular(x)*y;
}
friend modular operator/(ll x,const modular&y){
return modular(x)/y;
}
friend ostream& operator<<(ostream&os,const modular&m){
return os<<m.v;
}
friend istream& operator>>(istream&is,modular&m){
ll x;is>>x;
m=modular(x);
return is;
}
bool operator<(const modular&r)const{return v<r.v;}
bool operator==(const modular&r)const{return v==r.v;}
bool operator!=(const modular&r)const{return v!=r.v;}
explicit operator bool()const{
return v;
}
};
#ifndef DYNAMIC_MOD
extern constexpr modinfo base{998244353,3};
//extern constexpr modinfo base{1000000007,0};
//extern constexpr modinfo base{2147483579,0};//2^31 未満の最大の安全素数
//modinfo base{1,0};
#ifdef USE_GOOD_MOD
static_assert(base.mod==998244353);
#endif
#else
modinfo base(1,0);
extern constexpr modinfo base107(1000000007,0);
using mint107=modular<base107>;
#endif
using mint=modular<base>;
mint parity(int i){
return i%2==0?1:-1;
}
//Range add,sum
struct N{
int len;
mint sum,lz;
N():len(0),sum(0),lz(0){}
N(int LEN,mint val):len(LEN),sum(val),lz(0){}
void add(mint v){
sum+=v*len;
lz+=v;
return;
}
void push(N&x,N&y){
x.add(lz);
y.add(lz);
lz=0;
}
static N merge(N x,N y){
return N(x.len+y.len,x.sum+y.sum);
}
};
struct MaxNode{
pi v;
MaxNode(pi vv=pi(-inf,-1)):v(vv){}
static MaxNode merge(const MaxNode&a,const MaxNode&b){
return MaxNode(max(a.v,b.v));
}
bool ok(pi z){
return v<z;
}
};
bool dbg=false;
vc<mint> calc(vc<pi> ai){
int n=si(ai);
segtree<MaxNode> seg(ai);
vc<N> ini(n+1,N(1,0));
ini[0].sum=1;
seglazy<N> dp(ini);
rep(i,n){
int l=seg.min_left(i,&MaxNode::ok,ai[i]).a;
int r=seg.max_right(i+1,&MaxNode::ok,ai[i]).a;
if((i-l)<(r-i-1)){
rng(j,l,i+1){
int kmin=max(j+ai[i].a,i+1);
int kmax=r;
if(kmin<=kmax){
mint val=dp.point_get(j).sum;
dp.ch(kmin,kmax+1,&N::add,val);
}
}
}else{
rng(k,i+1,r+1){
int jmin=l;
int jmax=min(k-ai[i].a,i);
if(jmin<=jmax){
mint val=dp.composite(jmin,jmax+1).sum;
dp.point_change(k,&N::add,val);
}
}
}
}
vc<mint> res(n+1);
rep(i,n+1)res[i]=dp.point_get(i).sum;
return res;
}
void slv(){
int n;
if(!dbg){
cin>>n;
if(n<0)dbg=true;
}
if(dbg){
static int itr=0;
itr++;
const int vmax=itr/1000+1;
n=rand_int(1,vmax);
}
vi a;
if(dbg){
rep(i,n)a.pb(rand_int(1,n));
}else{
a=readvi(n);
}
vc<pi> ai(n);
rep(i,n)ai[i]=pi(a[i],i);
vc<mint> dp[2];
rep(step,2){
dp[step]=calc(ai);
rein(ai);
}
rein(dp[1]);
vc<mint> ans(n,dp[0][n]);
rep(i,n)ans[i]+=dp[0][i]*dp[1][i+1];
dmp(dp[0]);
dmp(dp[1]);
dmp(ans);
rep(step,2){
vc<mint> sum[2];
rep(k,2)sum[k]=presum(dp[k]);
segtree<MaxNode> seg(ai);
auto eval=[&](int jmin,int jmax,int kmin,int kmax,int w){
assert(jmin<=jmax);
assert(kmin<=kmax);
mint res=0;
if(jmax-jmin<kmax-kmin){
rng(j,jmin,jmax+1){
int l=max(kmin,j+w);
int r=kmax;
if(l<=r){
res+=dp[0][j]*(sum[1][r+1]-sum[1][l]);
}
}
}else{
rng(k,kmin,kmax+1){
int l=jmin;
int r=min(jmax,k-w);
if(l<=r){
res+=(sum[0][r+1]-sum[0][l])*dp[1][k];
}
}
}
return res;
};
vi pos;
rep(i,n){
if(step==0){
int jmin=seg.min_left(i,&MaxNode::ok,ai[i]).a;
int jmax=i;
int kmin=i+1;
int kmax=seg.max_right(i+1,&MaxNode::ok,ai[i]).a;
ans[(step==0?i:n-1-i)]-=eval(jmin,jmax,kmin,kmax,ai[i].a);
}
auto work=[&](int x){
int jmin=seg.min_left(x,&MaxNode::ok,ai[x]).a;
int jmax=x;
int kmin=i+1;
int kmax=seg.max_right(i+1,&MaxNode::ok,ai[x]).a;
ans[(step==0?i:n-1-i)]+=eval(jmin,jmax,kmin,kmax,ai[x].a);
};
while(si(pos)&&ai[pos.back()]<ai[i]){
work(gpp(pos));
}
pos.pb(i);
}
rein(ai);
rep(k,2)rein(dp[k]);
swap(dp[0],dp[1]);
dmp(ans);
}
print(ans);
}
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
cout<<fixed<<setprecision(20);
slv();
if(dbg){
while(1)slv();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3804kb
input:
5 1 3 2 1 2
output:
3 6 3 3 6
result:
ok 5 tokens
Test #2:
score: 0
Accepted
time: 338ms
memory: 21220kb
input:
200000 15922 15391 11782 4758 1973 19909 16800 6438 3821 986 18599 2011 338 19886 12401 4169 11143 12665 3230 12565 15065 15056 5090 16908 13677 12634 11435 1425 8647 3876 10694 12256 3853 19901 5723 11065 6147 13613 13768 15794 14993 5819 8117 13871 14708 15099 7152 9810 14438 10557 3209 1265 13915...
output:
157122482 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 826457499 ...
result:
ok 200000 tokens
Test #3:
score: 0
Accepted
time: 347ms
memory: 21372kb
input:
200000 4065 9196 2588 18803 10818 17671 10483 13134 12147 19916 19382 19338 8864 7637 19542 14938 16362 7115 9159 9711 17907 17653 10175 3279 7471 3465 14016 13951 8676 2856 16709 5372 12237 18083 11052 16398 7140 9730 8800 18999 16808 8729 7608 6668 7049 6024 7892 18039 7278 12417 2440 13112 4039 5...
output:
47583147 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 345009231 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 370164779 3...
result:
ok 200000 tokens
Test #4:
score: 0
Accepted
time: 499ms
memory: 21304kb
input:
200000 1 1 1 1 4547 1 1 1 1 1 1 1 6329 1 1 19778 1 1 12258 1 1 1 1 1 18104 1 8123 1 329 1 1 1 1 1 1 1 1 4438 1 1 1 1 1 208 1 1 1 1 1 1 1 1 1 15603 1 1 1 1 1 1 1 1 1 1 5513 1 1 15427 1 1 1 1 1 1 1 18309 1 1 6333 1 1 1 1 1 1 1 1 1 13938 1 1 1 1 1 1 9229 1 1 1 1 1 1 1 1 1791 1 1 1 11747 1 1 1 1 8992 1 ...
output:
225508548 225508548 225508548 225508548 748768610 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 225508548 ...
result:
ok 200000 tokens
Test #5:
score: 0
Accepted
time: 512ms
memory: 21056kb
input:
200000 1 1 1 1 1 1 1 10166 1 1 9410 1 1 1 1 1 1 1 1 1 296 1 1 1 1 1 1 1 1 1 1 7392 4057 17616 1 1 1 1 3084 14799 1 1 13598 1 1 9848 1 1 1 1 1 8084 1 1 1 1 1 1 1 1 10519 1 1 1 1 1 14 1 1 1 1 1 1 1 1 1 1 14981 1 1 1 1 1 1 1 1 1 5144 7784 1 1 1 1 1 1 1 19661 1 14894 1 1 1 1 1 1 1 1 10449 1 1 1 16473 1 ...
output:
735167914 735167914 735167914 735167914 735167914 735167914 735167914 211149010 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 735167914 ...
result:
ok 200000 tokens
Test #6:
score: 0
Accepted
time: 681ms
memory: 21188kb
input:
200000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 1 6 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 6 1 1 1 1 1 1 1 1 6 1 1 1 2397 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 415221870 450552969 425969980 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 450552969 ...
result:
ok 200000 tokens
Test #7:
score: 0
Accepted
time: 669ms
memory: 21176kb
input:
200000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9861 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1739 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11012 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1...
output:
723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 723674232 76256586 723674232 723674232 723674232 723674232 723674232 723674232 7...
result:
ok 200000 tokens
Test #8:
score: 0
Accepted
time: 969ms
memory: 21192kb
input:
200000 1 1 1 1 1 1 1 1 1 1 29 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 1 1 1...
output:
529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 773664190 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 529842888 ...
result:
ok 200000 tokens
Test #9:
score: 0
Accepted
time: 968ms
memory: 21188kb
input:
200000 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
output:
806160702 806160702 806160702 806160702 806160702 364515698 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 806160702 331355896 806160702 806160702 806160702 806160702 806160702 806160702 806160702 ...
result:
ok 200000 tokens
Test #10:
score: -100
Time Limit Exceeded
input:
200000 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 ...