P5107 能量采集
观察数据范围发现 \(n\) 很小而 \(t\) 很大,于是我们想到矩阵快速幂。我们可以直接建 \(n \times n\) 的转移矩阵 \(A\),设 \(u\) 的出边为 \(d_u\) 条,边 \((u,v)\) 共有 \(cnt_{(u,v)}\) 条(注意重边要计算多次即 \(cnt_{(u,v)}\) 可能大于一),则 \(A_{v,u} \equiv \dfrac{cnt_{(u,v)}}{d_u} \pmod {998244353}\),再定义 \(n \times 1\) 的初始矩阵 \(B\) 其中 \(B_{i,1} \equiv a_i \pmod {998244353}\)。则询问 \(t\) 的答案即为 \(A^t \times B\)。此时时间复杂段为 \(\mathcal{O}(qn^3 \log t)\),卡卡常能过不太能过。
我们考虑进行优化。我们考虑快速幂的过程,据一个例子 \(t=13\),则我们实际计算的是 \(A^8 \times A^4 \times A^1 \times B\)。而矩阵乘法具有结合律,我们可以优化计算顺序:\(A^8 \times (A^4 \times (A^1 \times B))\),我们发现 \(A^{2^k}\) 与 \(B\) 相乘的复杂度仅为 \(\mathcal{O}(n^2)\),而由于转移矩阵是已知的,那么 \(A^{2^k}\) 是可以预处理的。于是我们成功把时间复杂度降为了 \(\mathcal{O}(n^3 \log t + qn^2 \log t)\),能过。
// 火车头
const int mod=998244353;
const int N=55;
struct Matrix {
	int n,m,a[N][N];
	Matrix(int l=0,int c=0) {
		n=l,m=c,memset(a,0,sizeof(a));
		return ;
	}
	inline void init(int d) {
		n=m=d,memset(a,0,sizeof(a));
		for(int i=1;i<=d;i++) a[i][i]=1;
		return ;
	}
	inline Matrix operator *(const Matrix &tmp) const {
		Matrix res(n,tmp.m);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
				for(int k=1;k<=tmp.m;k++)
					add(res.a[i][k],(ll)a[i][j]*tmp.a[j][k]%mod);
		return res;
	}
};
int n,m,q;
vector<int> edge[N];
Matrix ret[30],stat;
inline ll quickpow(ll base,ll p) {
	ll tmp=1;
	for(;p;p>>=1) {
		if(p&1) tmp=tmp*base%mod;
		base=base*base%mod;
	}
	return tmp;
}
inline Matrix quickpow_matrix(ll p) {
	Matrix tmp=stat;
	for(int i=0;i<30;i++)
		if((p>>i)&1) tmp=ret[i]*tmp;
	return tmp;
}
int main() {
	read(n),read(m),read(q);
	stat=Matrix(n,1);
	for(int i=1;i<=n;i++) read(stat.a[i][1]),edge[i].pb(i);
	for(int i=1,u,v;i<=m;i++) read(u),read(v),edge[u].pb(v);
	ret[0]=Matrix(n,n);
	for(int i=1;i<=n;i++) {
		ll c=quickpow(edge[i].size(),mod-2);
		for(int v:edge[i]) add(ret[0].a[v][i],c);
	}
	for(int i=1;i<30;i++) ret[i]=ret[i-1]*ret[i-1];
	for(int i=1,t;i<=q;i++) {
		read(t);
		Matrix res=quickpow_matrix(t);
		ll ans=0;
		for(int i=1;i<=n;i++) ans^=res.a[i][1];
		write(ans%mod),_E;
	}
	return 0;
}
点个赞再走喵 qaq

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号