【题解】洛谷 P7245 灯光效果
分析 + 题解
容易发现,被操作的区域恰好可以分成
具体地,对于所有满足
枚举
说明:一共有
设
设
其中
构造如下矩阵,使用矩阵快速幂即可在
总时间复杂度为
代码
如果还有不清楚的,就看代码吧。
#include<bits/stdc++.h>
using namespace std;
const int P=998244353;
inline void add(int &a,int b)
{
a=a+b-(a+b>=P?P:0);
}
inline void mul(int &a,int b)
{
a=1ll*a*b%P;
}
inline int get_sum(int a,int b)
{
return a+b-(a+b>=P?P:0);
}
inline int get_product(int a,int b)
{
return 1ll*a*b%P;
}
inline int get_square(int x)
{
return get_product(x,x);
}
inline int get_power(int a,int n)
{
int res=1;
while(n>0)
{
res=(n&1)?get_product(res,a):res;
mul(a,a);
n>>=1;
}
return res;
}
inline int get_inv(int x)
{
return get_power(x,P-2);
}
//以上是模运算中的加、乘、平方、快速幂、求逆
const int max_m=1e3+5;
int x[max_m],y[max_m];
struct matrix
{
int v[2][2];
inline matrix(int p=0)//matrix 的构造函数,用概率 p 构造上述矩阵
{
v[0][0]=v[1][1]=P+1-p;
v[0][1]=v[1][0]=p;
}
};
inline matrix operator * (const matrix &a,const matrix &b)//定义矩阵乘法
{
static matrix res;//static 变量会沿用上一次的结果,若需初始化必须在定义后赋值
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
{
res.v[i][j]=0;
for(int k=0;k<2;++k)
add(res.v[i][j],get_product(a.v[i][k],b.v[k][j]));
}
return res;
}
inline matrix get_power(matrix a,int n)//矩阵快速幂
{
static matrix res;
res.v[0][0]=1;
res.v[0][1]=res.v[1][0]=res.v[1][1]=0;
while(n)
{
if(n&1)
res=res*a;
a=a*a;
n>>=1;
}
return res;
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;++i)
scanf("%d",x+i);
for(int i=1;i<=m;++i)
scanf("%d",y+i);
int inv_all=get_square(get_inv((1ll*m*(m-1)>>1)%P));//概率的分母
int ans=0;
for(int i=1;i<m;++i)
for(int j=1;j<m;++j)
{
int cnt=get_product(x[i+1]-x[i],y[j+1]-y[j]);//元素个数
int p=get_product(get_product(get_product(i,j),get_product(m-i,m-j)),inv_all);//概率
add(ans,get_product(cnt,get_power(matrix(p),k).v[0][1]));
}
printf("%d\n",ans);
return 0;
}