luogu P5472 [NOI2019] 斗主地
我是真服了,猜结论这么牛逼。我tm应该猜个二次函数就写哪这个多废话。
首先看这个形式\(\frac{X}{X+Y}\)感觉非常不爽,然后看样例发现所有能合并出来的序列的概率式一样的。
所以就猜概率是一样的,进一步得出概率是\(\frac{1}{C_{n}^{A_i}}\)。
证明就考虑每次操作是下面一定是从\(n\)一直减一到\(1\),上面两边分别从\(A_i\)和\(n-A_i\)减到\(1\),乘起来就是这个概率。
然后你手摸一下样例发现一次函数塞进去后这个期望也是一个一次函数。
然后你xjb乱拆系数范德蒙特卷积是可以化简证明出来的。做题的时候的过程卸载下面。
\(b_i=\sum\limits_{j=1}^{\min(A_k,i)}{C_{i-1}^{j-1}C_{n-i}^{A_k-j}j+\sum\limits_{j=A_k+1}^{\min(n,A_k+i)}{C_{i-1}^{j-A_k-1}C_{n-i}^{n-j}j}}\)
\(=\sum\limits_{j=1}^{\min(A_k,i)}{(j-1)C_{i-1}^{j-1}C_{n-i}^{A_k-j}+C_{i-1}^{j-1}C_{n-i}^{A_k-j}}+\sum\limits_{j=A_k+1}^{\min(n,A_k+i)}{C_{i-1}^{j-A_k-1}C_{n-i}^{n-j}(j-A_k-1)+(A_k+1)C_{i-1}^{j-A_k-1}C_{n-i}^{n-j}}\)
\(=C_{n-1}^{A_k-1}+(A_k+1)C_{n-1}^{A_k+1}+\sum\limits_{j=1}^{\min(A_k,i)}{(i-1)C_{i-2}^{j-2}C_{n-i}^{A_k-j}}+\sum\limits_{j=A_k+1}^{\min(n,A_k+i)}{C_{i-2}^{j-A_k-2}C_{n-i}^{n-j}(i-1)}\)
\(=C_{n-1}^{A_k-1}+(A_k+1)C_{n-1}^{A_k}+(i-1)(C_{n-2}^{A_k-2}+C_{n-2}^{A_k})\)
\(P=\frac{A_k}{n}+\frac{(n-A_k)(A_k+1)}{n}+(i-1)(\frac{A_k(A_k-1)}{n(n-1)}+\frac{(n-A_k)(n-A_k-1)}{n(n-1)})\)
然后进一步猜一猜二次函数塞进去也是二次函数。按照上面的方法一样推就好了。
\(c_i=\sum\limits_{j=1}^{\min(A_k,i)}{C_{i-1}^{j-1}C_{n-i}^{A_k-j}j^2}+\sum\limits_{j=A_k+1}^{\min(n,A_k+i)}{C_{i-1}^{j-A_k-1}C_{n-i}^{n-j}j^2}\)
\(=\sum\limits_{j=1}^{\min(A_k,i)}{C_{i-1}^{j-1}C_{n-i}^{A_k-j}((j-1)(j-2)+3(j-1)+1)}+\sum\limits_{j=A_k+1}^{\min(n,A_k+i)}{C_{i-1}^{j-A_k-1}C_{n-i}^{n-j}((n-j)(n-j-1)-(2n-1)(n-j)+n^2)}\)
\(=C_{n-1}^{A_k-1}+3(i-1)C_{n-2}^{A_k-2}+(i-1)(i-2)C_{n-3}^{A_k-3}+(n-i)(n-i-1)C_{n-3}^{A_k}-(n-i)(2n-1)C_{n-2}^{A_k}+n^2C_{n-1}^{A_k}\)
\(=\frac{A_k}{n}+\frac{3A_k(A_k-1)(i-1)}{n(n-1)}+\frac{(i-1)(i-2)A_k(A_k-1)(A_k-2)}{n(n-1)(n-2)}+n(n-A_k)-\frac{(n-i)(2n-1)(n-A_k)(n-A_k-1)}{n(n-1)}+\frac{(n-i)(n-i-1)(n-A_k)(n-A_k-1)(n-A_k-2)}{n(n-1)(n-2)}\)
\(Ans.c=\frac{A_k}{n}-\frac{3A_k(A_k-1)}{n(n-1)}+\frac{2A_k(A_k-1)(A_k-2)}{n(n-1)(n-2)}+n(n-A_k)-\frac{(2n-1)(n-A_k)(n-A_k-1)}{n-1}+\frac{(n-A_k)(n-A_k-1)(n-A_k-2)}{n-2}\)
\(Ans.b=\frac{3A_k(A_k-1)}{n(n-1)}-\frac{3A_k(A_k-1)(A_k-2)}{n(n-1)(n-2)}+\frac{(2n-1)(n-A_k)(n-A_k-1)}{n(n-1)}-\frac{(2n-1)(n-A_k)(n-A_k-1)(n-A_k-2)}{n(n-1)(n-2)}\)
\(Ans.a=\frac{A_k(A_k-1)(A_k-2)}{n(n-1)(n-2)}+\frac{(n-A_k)(n-A_k-1)(n-A_k-2)}{n(n-1)(n-2)}\)
然后直接模拟即可,时间复杂度\(O(m+q)\)
code:
#include<bits/stdc++.h>
#define I inline
#define ll long long
#define db double
#define lb long db
#define N (500000+5)
#define M ((N<<1)+5)
#define K (700+5)
#define mod 998244353
#define Mod (mod-1)
#define eps (1e-5)
#define ull unsigned ll
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((k+1)*(x)+(y))
#define R(n) (rnd()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using namespace std;
int n,m,op;ll I1,I2,I3,x;
I ll mpow(ll x,int y=mod-2){ll Ans=1;while(y) y&1&&(Ans=Ans*x%mod),y>>=1,x=x*x%mod;return Ans;}
struct Node{ll a,b,c;Node operator +(const Node &B)const{return (Node){a+B.a,b+B.b,c+B.c};};}Ans;
I Node A3(ll c,ll x){return (Node){0,0,c};}I Node A2(ll b,ll x){Node C;C.a=C.b=C.c=0;C.b=(x*(x-1)+(n-x)*(n-x-1))%mod*I2%mod*I1%mod*b%mod;C.c=(x+(n-x)*(x+1))%mod*b%mod*I1%mod-C.b;return C;}
I Node A1(ll a,ll x){return (Node){(x*(x-1)%mod*(x-2)+(n-x)*(n-x-1)%mod*(n-x-2))%mod*I1%mod*I2%mod*I3%mod*a%mod,((3*x*(x-1)+(2*n-1)*(n-x)%mod*(n-x-1))-(3*x*(x-1)%mod*(x-2)+(2*n-1)*(n-x)%mod*(n-x-1)%mod*(n-x-2))%mod*I3)%mod*I1%mod*I2%mod*a%mod,(((2*(x-2)*I3-3)%mod*(x-1)%mod*I2%mod+1)*x%mod*I1%mod+n*(n-x)%mod-(2*n-1)*(n-x)%mod*(n-x-1)%mod*I2%mod+(n-x)*(n-x-1)%mod*(n-x-2)%mod*I3%mod)*a%mod};}
int main(){
freopen("1.in","r",stdin);
scanf("%d%d%d",&n,&m,&op);if(op==1) Ans=(Node){0,1,0};else Ans=(Node){1,0,0};I1=mpow(n);I2=mpow(n-1);I3=mpow(n-2);
while(m--)scanf("%lld",&x),Ans=A3(Ans.c,x)+A2(Ans.b,x)+A1(Ans.a,x),Ans.a%=mod,Ans.b%=mod,Ans.c%=mod;scanf("%d",&m);while(m--) scanf("%d",&x),printf("%lld\n",((Ans.c+x*Ans.b+1ll*x*x%mod*Ans.a)%mod+mod)%mod);
}