专栏文章
题解:AT_abc431_f [ABC431F] Almost Sorted 2
AT_abc431_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min8sxqp
- 此快照首次捕获于
- 2025/12/01 22:26 3 个月前
- 此快照最后确认于
- 2025/12/01 22:26 3 个月前
思路
唯一的区别就是本题当 相同时看做 个答案。而另一题中原来 值相同但位置不同被看做多个答案。
题目要求 或 。由于 没到 ,猜测为 。
发现可以用双指针做。直接排序(注意是降序)。我们对于每一个 ,找到最远的 ,使其满足条件,即 。该部分答案即为 。答案求累乘。乘法原理证明。由于 单调不降,则时间复杂度瓶颈在排序的 。这样就搞定了双倍经验那题。
然后你的样例一错了……
你发现当 相同时看做 个答案。所以我们要除去每种值出现多的部分。考虑用 记录 元素出现次数。则不难发现,对于值 ,你需要除以掉 。考虑费马小定理求逆元。
即原本答案为 ,则现在的答案就是 。
总时间复杂度为 。
代码
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
const int mod=998244353;
int n,d,a[N],ans=1;
map <int,int> mp;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1) ans=ans*a%mod;
a=a*a%mod,b>>=1;
}return ans;
}
signed main(){
scanf("%lld%lld",&n,&d);
for(int i=1;i<=n;i++) scanf("%lld",a+i),mp[a[i]]++;
sort(a+1,a+n+1,greater<int>());
for(int l=1,r=1;r<=n;r++){
while(a[l]-d>a[r]) l++;
ans=ans*(r-l+1)%mod;
}
for(auto i:mp)
for(int j=1;j<=i.second;j++) ans=ans*qpow(j,mod-2)%mod;
printf("%lld",ans);
return 0;
}
撒花!
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...