专栏文章

CF1332E Height All the Same 题解

CF1332E题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mimzlkmp
此快照首次捕获于
2025/12/01 18:09
3 个月前
此快照最后确认于
2025/12/01 18:09
3 个月前
查看原文
可以用生成函数和多项式取模做。本质上和矩阵乘法差不多,但是更好写。
观察发现,若所有位置奇偶性相同,则用操作二可以做到合法。操作一可以看作反转相邻两个位置的奇偶性。
当且仅当奇数高度位置的个数为奇数个,且偶数高度位置的个数为奇数个,无解。否则有解。
按照 n×mn \times m 的奇偶性分类讨论。只有 2n×m2 \mid n \times m 时可能出现上述无解情况。
只需要求,n×mn \times m 个位置,每个位置可以填 AA 种奇数,或者 BB 种偶数。求 填奇数的位置 有偶数个,的方案数。
生成函数 f(x)=ax+bf(x) = ax+b[x1][x^1] 表示 填奇数的位置 有奇数个的方案数,[x0][x^0] 表示 填奇数的位置 有偶数个的方案数。
需要求 [x0](Ax+B)n×m(modx21)[x^0] (Ax+B)^{n\times m} \pmod{x^2-1}。注意是多项式取模。
其实不需要会多项式取模,只是在多项式快速幂的过程中,把 x2x^2 换成 x0x^0。因为 0,20,2 奇偶性相同。
不用动脑子而且比矩阵好写一点。
CPP
#include<bits/stdc++.h>
#define sf scanf 
#define pf printf 
#define rep(x,y,z) for(int x=y;x<=z;x++) 
#define per(x,y,z) for(int x=y;x>=z;x--) 
using namespace std;
typedef long long ll;
namespace wing_heart {
	constexpr int mod=998244353;
	struct modint {
		int x;
		modint (int y=0) : x(y) {} 
		modint operator + (modint b) const { return x+b.x<mod ? x+b.x : x+b.x-mod; }
		modint operator * (modint b) const { return 1ll*x*b.x%mod; }
		modint &operator += (modint b) { return *this = *this + b; } 
		modint &operator *= (modint b) { return *this = *this * b; } 
	};
	modint ksm(modint a,ll b) {
		modint s=1;
		while(b) {
			if(b&1) s*=a;
			a*=a;
			b>>=1;
		}
		return s;
	}
	struct poly {
		modint x1,x0;
		poly operator + (poly b) const { return {x1+b.x1,x0+b.x0}; }
		poly operator * (poly b) const { return {x1*b.x0+x0*b.x1,x0*b.x0+x1*b.x1}; }
		poly &operator += (poly b) { return *this = *this + b; }
		poly &operator *= (poly b) { return *this = *this * b; }
	};
	poly ksm_poly(poly a,ll b) {
		poly s = {0,1};
		while(b) {
			if(b&1) s*=a;
			a*=a;
			b>>=1;
		}
		return s;
	}
	int n,m,l,r;
	int A,B;
	int solve() {
		poly t = ksm_poly({A,B},1ll*n*m);
		return t.x0.x;
	}
	void main() {
		sf("%d%d%d%d",&n,&m,&l,&r);
		if((1ll*n*m)&1) pf("%d\n",ksm(r-l+1,1ll*n*m).x), exit(0);
		if((l&1)^(r&1)) A=B=(r-l+1)>>1;
		else if(l&1) A=(r-l+2)>>1, B=(r-l)>>1;
		else A=(r-l)>>1, B=(r-l+2)>>1;
		pf("%d\n",solve());
	}
}
int main() {
	wing_heart :: main();
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...