QOJ.ac
QOJ
ID | 提交记录ID | 题目 | Hacker | Owner | 结果 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|
#618 | #333363 | #7899. Say Hello to the Future | zyxawa | zyxawa | Failed. | 2024-05-10 21:19:05 | 2024-05-10 21:19:05 |
詳細信息
Extra Test:
Accepted
time: 0ms
memory: 8412kb
input:
6 1 1 4 5 1 4
output:
2 2 2 4 2 3
result:
ok 6 tokens
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#333363 | #7899. Say Hello to the Future | zyxawa | AC ✓ | 331ms | 113184kb | C++14 | 2.4kb | 2024-02-19 20:57:41 | 2024-02-19 20:57:42 |
answer
#include<bits/stdc++.h>
using namespace std;
#define mid ((l+r)/2)
struct node{
int x,d,v;
node(int x=0,int d=0,int v=0):x(x),d(d),v(v){}
};
int n,a[200001],b[200001],p[200001];
long long f[210001],g[210001],ans[200001];
vector <node> G[200001];
const int mod=998244353;
struct tree{
long long n,t[200001];
void init(int m){n=m;for(int i=1;i<=n;i++)t[i]=0;}
void add(int x,int v){for(int i=x;i<=n;i+=i&-i)(t[i]+=v)%=mod;}
long long ask(int x){long long s=0;for(int i=x;i>=1;i-=i&-i)(s+=t[i])%=mod;return s;}
}t;
bool cmp(int x,int y){return b[x]<b[y];}
void cdq(long long *dp,int l,int r){
if(l==r){
if(a[l]==1) (dp[l]+=dp[l-1])%=mod;
return;
}
cdq(dp,l,mid),t.init(mid-l+1);
for(int i=mid,mx=0;i>=l;i--) mx=max(mx,a[i]),b[i]=i+mx-1,p[i]=i;
for(int i=mid+1,mx=0;i<=r;i++) mx=max(mx,a[i]),b[i]=i-mx+1;
sort(p+l,p+mid+1,cmp);
for(int i=mid+1,j=l;i<=r;i++){
while(j<=mid&&i>=b[p[j]]) t.add(p[j]-l+1,dp[p[j]-1]),j++;
(dp[i]+=t.ask(min(b[i],mid)-l+1))%=mod;
}
cdq(dp,mid+1,r);
}
void solve(int l,int r){
if(l==r){
if(a[l]!=1) (ans[l]+=f[l-1]*g[l+1])%=mod;
return;
}
solve(l,mid),solve(mid+1,r);
for(int i=mid,mx=0;i>=l;i--) mx=max(mx,a[i]),b[i]=i+mx-1;
for(int i=mid+1,mx=0;i<=r;i++) mx=max(mx,a[i]),b[i]=i-mx+1;
t.init(mid-l+1);
for(int i=mid+1;i<=r;i++) G[i].clear();
for(int i=mid,mx1=0,mx2=0,p=0;i>=l;i--){
if(a[i]>mx1) mx2=mx1,mx1=a[i],p=i;
else if(a[i]>mx2) mx2=a[i];
if(i+mx1-1<=r) G[max(mid+1,i+mx1-1)].push_back(node(i,p,mod-f[i-1]));
if(i+mx2-1<=r) G[max(mid+1,i+mx2-1)].push_back(node(i,p,f[i-1]));
}
for(int i=r;i>mid;i--){
if(b[i]>=l) t.add(min(b[i],mid)-l+1,g[i+1]);
for(auto j:G[i]) (ans[j.d]+=j.v*(t.ask(mid-l+1)-t.ask(j.x-l)+mod))%=mod;
}
t.init(r-mid);
for(int i=l;i<=mid;i++) G[i].clear();
for(int i=mid+1,mx1=0,mx2=0,p=0;i<=r;i++){
if(a[i]>mx1) mx2=mx1,mx1=a[i],p=i;
else if(a[i]>mx2) mx2=a[i];
if(i-mx1+1>=l) G[min(i-mx1+1,mid)].push_back(node(i,p,mod-g[i+1]));
if(i-mx2+1>=l) G[min(i-mx2+1,mid)].push_back(node(i,p,g[i+1]));
}
for(int i=l;i<=mid;i++){
if(b[i]<=r) t.add(max(mid+1,b[i])-mid,f[i-1]);
for(auto j:G[i]) (ans[j.d]+=j.v*t.ask(j.x-mid))%=mod;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
f[0]=g[0]=1,cdq(f,1,n),reverse(a+1,a+1+n),cdq(g,1,n),reverse(a+1,a+1+n),reverse(g,g+2+n),solve(1,n);
for(int i=1;i<=n;i++) printf("%lld ",(f[n]+ans[i])%mod);
return 0;
}