题面
题解
首先询问和原数列顺序无关,那么不妨把数列从大到小排序,仍记为 \(a_i\)。
那么题目就是给出 \([l,r]\),问 \(a_l,a_{l+1},\cdots,a_r\) 中任取 \(k\) 个数,这 \(k\) 个数中最大值的期望。
由于这是等概率选择,每种情况出现的概率为 \(\dfrac{1}{\binom{m}{k}}\)(记 \(m=r-l+1\)),所以我们只需计算每种情况的最大值之和即可。
容易想到直接枚举最大值为 \(a_i\),那么剩余的 \(k-1\) 个数就必须从 \(a_{i+1},a_{i+2},\cdots,a_r\) 里面选,方案数为 \(\dbinom{r-i}{k-1}\),故最大值为 \(a_i\) 的贡献为 \(a_i\times \dbinom{r-i}{k-1}\)。
所以总和即为 \(\sum\limits_{i=l}^r \dbinom{r-i}{k-1}\times a_i\)。
总时间复杂度 \(O(nq)\),上述部分都是比较容易想到的。
注意到 \(\sum k\leq 10^5\),考虑把单次询问从 \(O(n)\) 向 \(O(k)\) 转换。
受到 subtask4 的启发,我们设 \(f_k[r]=\sum\limits_{i=1}^r\dbinom{r-i}{k-1}\times a_i\),那么每次询问 \([l,r]\) 的答案即为:
\[f_k[r]-\sum_{i=1}^{l-1}\dbinom{r-i}{k-1}\times a_i \]试图也用 \(f\) 来表示 \(\sum\limits_{i=1}^{l-1}\dbinom{r-i}{k-1}\times a_i\):
\[\begin{aligned} &\sum_{i=1}^{l-1}\dbinom{r-i}{k-1}\times a_i\\ =&\sum_{i=1}^{l-1}\sum_{j=0}^{k-1}\dbinom{r-l+1}{j}\dbinom{l-1-i}{k-1-j}\times a_i \end{aligned} \](上面这步用到了范德蒙德卷积)
范德蒙德卷积:
\[\sum_{i=0}^{k}\dbinom{n}{i}\dbinom{m}{k-i}=\dbinom{n+m}{k} \]证明:从组合意义上即可理解,相当于从各有 \(n\) 个和 \(m\) 个的两堆中共取出 \(k\) 个球。
继续推:
\[\begin{aligned} &\sum_{i=1}^{l-1}\dbinom{r-i}{k-1}\times a_i\\ =&\sum_{i=1}^{l-1}\sum_{j=0}^{k-1}\dbinom{r-l+1}{k-1-j}\dbinom{l-1-i}{j}\times a_i\\ =&\sum_{i=1}^{l-1}\sum_{j-1}^{k}\dbinom{r-l+1}{k-j}\dbinom{l-1-i}{j-1}\times a_i\\ =&\sum_{j-1}^{k}\dbinom{r-l+1}{k-j}\sum_{i=1}^{l-1}\dbinom{l-1-i}{j-1}\times a_i\\ =&\sum_{j-1}^{k}\dbinom{r-l+1}{k-j}f_{j}[l-1]\\ \end{aligned} \]故每次询问 \([l,r]\) 的答案就是:
\[f_k[r]-\sum_{j-1}^{k}\dbinom{r-l+1}{k-j}f_{j}[l-1] \]设 \(P=\sum k\),那么这样询问的总时间复杂度就是 \(O(q+P)\) 的了,但是如果暴力 \(O(kn^2)\) 预处理 \(f\) 的话我们是无法接受的。
考虑优化预处理的过程:
观察定义式 \(f_k[r]=\sum\limits_{i=1}^r\dbinom{r-i}{k-1}\times a_i\),由组合数递推公式 \(\dbinom{n}{m}=\dbinom{n-1}{m}+\dbinom{n-1}{m-1}\) 可知:
\[\begin{aligned} f_k[r]&=\sum\limits_{i=1}^r\dbinom{r-i}{k-1}\times a_i\\ &=\sum\limits_{i=1}^r\left[\dbinom{r-i-1}{k-1}+\dbinom{r-i-1}{k-2}\right]\times a_i\\ &=f_{k}[r-1]+f_{k-1}[r-1] \end{aligned} \]于是预处理 \(f\) 的时间复杂度由 \(O(kn^2)\) 降到了 \(O(kn)\),但这样还是不够。
我们考虑设置一个阈值 \(B\):
-
当 \(k> B\) 时我们使用最开始说的暴力算法,这种算法的使用次数不会超过 \(\dfrac{P}{B}\),总时间复杂度 \(O(\dfrac{nP}{B})\);
-
当 \(k\leq B\) 时我们先 \(O(nB)\) 预处理出所有的 \(f_k[r]\),然后再 \(O(q+P)\) 询问。
总时间复杂度 \(O(nB+\dfrac{nP}{B})\),注意到 \(n,P\) 同阶,取 \(B=\sqrt P\) 时有最优的时间复杂度 \(O(n\sqrt n)\)。
#include<bits/stdc++.h>
#define SN 320
#define N 100010
using namespace std;
namespace modular
{
const int mod=998244353;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
}using namespace modular;
inline int poww(int a,int b)
{
int ans=1;
while(b)
{
if(b&1) ans=mul(ans,a);
a=mul(a,a);
b>>=1;
}
return ans;
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int n,q,B,a[N],b[N];
int fac[N],ifac[N];
int f[SN][N];
int C(int n,int m)
{
if(n<0||m<0||m>n) return 0;
return mul(mul(fac[n],ifac[m]),ifac[n-m]);
}
int solve1(int l,int r,int k)
{
int ans=0;
for(int i=l;i<=r;i++)
ans=add(ans,mul(C(r-i,k-1),a[i]));
return ans;
}
int solve2(int l,int r,int k)
{
int ans=f[k][r];
for(int j=1;j<=k;j++)
ans=dec(ans,mul(C(r-l+1,k-j),f[j][l-1]));
return ans;
}
int main()
{
n=read(),q=read(),B=sqrt(n);
for(int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) b[i]=a[i];
reverse(a+1,a+n+1);
fac[0]=1;
for(int i=1;i<=100000;i++) fac[i]=mul(fac[i-1],i);
ifac[100000]=poww(fac[100000],mod-2);
for(int i=100000;i>=1;i--) ifac[i-1]=mul(ifac[i],i);
for(int r=1;r<=n;r++) f[1][r]=add(f[1][r-1],a[r]);
for(int k=2;k<=B;k++)
for(int r=1;r<=n;r++)
f[k][r]=add(f[k-1][r-1],f[k][r-1]);
while(q--)
{
int l=read(),r=read(),k=read();
l=lower_bound(b+1,b+n+1,l)-b;
r=upper_bound(b+1,b+n+1,r)-b-1;
swap(l,r);
l=n-l+1,r=n-r+1;
printf("%d ",r-l+1);
if(k>r-l+1)
{
puts("-1");
continue;
}
printf("%d\n",mul(k>B?solve1(l,r,k):solve2(l,r,k),poww(C(r-l+1,k),mod-2)));
}
return 0;
}
/*
7 3
83 74 100 89 95 79 72
90 100 3
80 89 1
70 79 2
*/
标签:return,dbinom,int,sum,times,intervcl,XSY4074,复杂度,根号
From: https://www.cnblogs.com/ez-lcw/p/16842964.html