CF1332E Height All the Same 题解
wing_heart · · 题解
可以用生成函数和多项式取模做。本质上和矩阵乘法差不多,但是更好写。
观察发现,若所有位置奇偶性相同,则用操作二可以做到合法。操作一可以看作反转相邻两个位置的奇偶性。
当且仅当奇数高度位置的个数为奇数个,且偶数高度位置的个数为奇数个,无解。否则有解。
按照
只需要求,
生成函数
需要求
其实不需要会多项式取模,只是在多项式快速幂的过程中,把
不用动脑子而且比矩阵好写一点。
#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();
}