题解:P10407 「SMOI-R1」Game
Supor__Shoep · · 题解
就我觉得 T3 比 T4 简单吗QAQ
首先有一个非常常规的思路:枚举每一个数,求出其作为最大值的区间个数。这道题也是如此。
如果最终的序列
但是需要注意,有的区间是会被算重的,比如
但是出题人非常可爱啊!这个
我们将
先考虑
我们记
每一个子段的顶点值我们就算完了,我们考虑将这种做法拓展到其它数上面。其实我们可以利用图像去思考:
我们知道对于每一个数,要去找前面和后面比自己大的,由于除了顶点以外,每个数的后面都有一个比自己大一的数,所以右侧比较好找。而对于左侧,我们结合上图去思考,不难发现最终形成的
但是对于每个数都用单调栈的话显然会寄。
我们可以找一下规律:
考虑对第
于是我们用单调栈去储存
这样就可以
根据单调栈的性质,可以推断
最后就是一些细节问题了,放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e6+5;
const int MOD=998244353;
int n,a[MAXN];
stack<int> stk;
int res;
int L[MAXN],R[MAXN];
int sum[MAXN];
int qpow(int x,int y)
{
int res=1;
while(y)
{
if(y&1) res=1ll*res*x%MOD;
x=1ll*x*x%MOD;
y>>=1;
}
return res;
}
int solve(int x,int y,int z){ return (1ll*x*y%MOD*z%MOD+1ll*(x+y)%MOD*(1ll*(z+1)*z/2%MOD)%MOD+1ll*z*(z+1)%MOD*(2*z+1)%MOD*qpow(6,MOD-2)%MOD)%MOD; }
signed main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],sum[i]=sum[i-1]+a[i],sum[i]%=MOD;
a[n+1]=a[n];
for(int i=1;i<=n;i++)
{
while(!stk.empty()&&a[stk.top()]<a[i]) R[stk.top()]=i,stk.pop();
if(!stk.empty()) L[i]=stk.top();
stk.push(i);
}
while(!stk.empty()) R[stk.top()]=n+1,stk.pop();
for(int i=1;i<=n;i++) res+=1ll*a[i]*(sum[i]-sum[L[i]]+MOD)%MOD*(sum[R[i]-1]-sum[i]+1+(R[i]<=n)*a[i]+MOD)%MOD,res%=MOD;
while(!stk.empty()) stk.pop();
stk.push(0),a[0]=1e9;
for(int i=1;i<=n;i++)
{
int lst=0;
while(!stk.empty()&&a[stk.top()]<=a[i]-1) res+=solve(sum[i-1]-sum[stk.top()]+lst,lst,a[stk.top()]-lst),lst=a[stk.top()],stk.pop();
if(lst!=a[i]-1) res+=solve(sum[i-1]-sum[stk.top()]+lst,lst,a[i]-lst-1),res%=MOD;
while(!stk.empty()&&a[stk.top()]==a[i]) stk.pop();
stk.push(i);
}
cout<<res;
return 0;
}