传送门
解析:
神题啊。。
思路:
首先要进行转化,即方差等于平方的期望减去期望的平方。
这么说好像不太浅显啊。
方差的定义大概就是这样一个式子: s 2 = 1 n ∑ ( x i − x ˉ ) 2 s^2=\frac{1}{n}\sum(x_i-\bar{x})^2 s2=n1∑(xi−xˉ)2
然后我们将它化简一下
s
2
=
1
n
∑
(
x
i
2
+
x
ˉ
2
−
2
x
i
x
ˉ
)
s^2=\frac{1}{n}\sum(x_i^2+\bar{x}^2-2 x_i\bar{x})
s2=n1∑(xi2+xˉ2−2xixˉ)
由于
x
ˉ
=
1
n
∑
x
i
\bar{x}=\frac{1}{n}\sum x_i
xˉ=n1∑xi,所以上面的式子可以化简为
s
2
=
∑
x
i
2
n
−
x
ˉ
2
s^2=\frac{\sum x_i^2}{n}-\bar{x}^2
s2=n∑xi2−xˉ2
那么我们要计算的就是 ∑ x i 2 \sum x_i^2 ∑xi2, n n n,和 ∑ x i = n x ˉ \sum{x_i}=n\bar{x} ∑xi=nxˉ。
首先我们要计算 ∑ x \sum{x} ∑x,就是每个矩阵把多少个点围住,换言之就是每个点被多少个矩阵围住。直接计算上下左右边界的组合方式就是我们要的 ∑ x \sum{x} ∑x
然后考虑计算
∑
x
i
2
\sum{x_i^2}
∑xi2,这个非常蛋疼,不过仍然有办法做,不理解的请感性理解一下。
就是直接枚举每个点对(包括自己与自己),计算将这个点对围住的有多少个矩形。可以用组合的思想来理解一下。
然后就是最蛋疼的地方了,计算 n n n,即,有多少个矩阵需要被统计在最后的答案当中。
枚举每一个点,统计以这个点为最左包含点的矩阵就可以了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
cs ll mod=998244353;
inline ll quickpow(ll a,ll b,ll res=1){
for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;
return res;
}
inline ll inv(ll a){return quickpow(a,mod-2);}
cs int N=2005;
struct node{
int x,y;
}a[N];
inline bool cmp(cs node &a,cs node &b){
return a.x==b.x?a.y<b.y:a.x<b.x;
}
ll exex,ex,tot;
int n,m,k;
signed main(){
n=getint();
m=getint();
k=getint();
for(int re i=1;i<=k;++i)a[i].x=getint(),a[i].y=getint();
for(int re i=1;i<=k;++i){
exex=(exex+1ll*(n-a[i].x+1)*(a[i].x)%mod*(m-a[i].y+1)%mod*(a[i].y)%mod)%mod;
for(int re j=1;j<=k;++j){
int r=max(a[i].x,a[j].x);
int l=min(a[i].x,a[j].x);
int u=max(a[i].y,a[j].y);
int d=min(a[i].y,a[j].y);
ex=(ex+1ll*(n-r+1)*(l)%mod*(m-u+1)%mod*(d)%mod)%mod;
}
}
a[++k]=(node){0,0};
sort(a+1,a+k+1,cmp);
for(int re i=1;i<=k;++i){
int u=m,d=1;
for(int re j=i-1;j;--j){
if(u<d)break;
if(a[j].x!=a[j+1].x)tot=(tot+1ll*(a[i].y-d+1)*(u-a[i].y+1)%mod*(n-a[i].x+1)%mod*(a[j+1].x-a[j].x)%mod)%mod;
if(a[j].y>=a[i].y)u=min(u,a[j].y-1);
if(a[j].y<=a[i].y)d=max(d,a[j].y+1);
}
}
ll itot=inv(tot);
exex=exex*itot%mod;
exex=exex*exex%mod;
ex=ex*itot%mod;
cout<<(ex-exex+mod)%mod;
return 0;
}