题解:P13662 「TPOI-5A」Luminescence
首先观察题目,很难不看出
那么一个合法的
同理,一个合法的
另外,考虑数字
到这里,我们完成了是否存在合法排列的判断。如果只是计算合法排列的数量,我们发现对于每个不确定
接下来考虑题目中给出的权值信息有什么用,可以看出其含义是计算所有区间的
那么考虑枚举
也就是:
对于统计有多少区间满足
到这里好像进行不下去了,我们考虑充分利用题目性质。注意到对于某个
于是对于每个
实现方面,在计算方案数时可以采用双指针来规避排序部分,同时也能完成权值的计算,时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define N 200020
#define MOD 998244353
int T,n,a[N],b[N];
int main()
{
scanf("%d",&T);
while(T--){
int flg=1;
scanf("%d",&n);
a[0]=b[n+1]=n;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
for(int i=1;i<=n;i++)if(a[i]>a[i-1])flg=0;
for(int i=1;i<=n;i++)if(b[i]>b[i+1])flg=0;
int l=1,r=n,m=-1;
for(int i=1;i<=n;i++)if(b[i]==0)m=i;
if(m==-1 || a[m]>0 || a[m-1]==0)flg=0;
if(!flg){
printf("0\n");
continue;
}
int ans=0,tot=1,lst=n,cnt=0;
while(l<=r){
int x=max(a[l],b[r]),t=1ll*l*(n-r+1)%MOD;
ans+=1ll*t*(lst-x)%MOD,ans%=MOD;
cnt+=lst-x-1;
lst=x;
if(l==r)break;
if(a[l]>b[r]){
l++;
while(a[l]==x && l<=n)l++,tot=1ll*tot*cnt%MOD,cnt--;
}
else{
r--;
while(b[r]==x && r>=1)r--,tot=1ll*tot*cnt%MOD,cnt--;
}
}
printf("%lld\n",1ll*tot*ans%MOD);
}
}