qoj #8147. Math Exam
qoj #8147. Math Exam
考虑 \(4a_1 = a_1^2 + 2a_1 + 1\),解得 \(a_1 = 1\)。
接下来考虑 \(4a_i = a_i^2 + 2a_i + 1 - a_{i-1}^2 - 2a_{i-1} - 1\)。
我们可以解得 \((a_{i-1}+1)^2 = (a_i - 1)^2\),则有两种情况:
-
\(a_i = a_{i-1} + 2\)
-
\(a_i = - a_{i-1}\)
我们令 \(b_i = \dfrac{|a_i + 1|}{2}\),显然 \(b_1 = 1\)。
接下来我们声称 \(b_i = b_{i-1} - 1\) 或 \(b_i = b_{i+1} + 1\)。
同时,因为 \(a_i \in [-m,m]\),得 \(b_i \in [0,\dfrac{m+1}{2}]\)。
通过计算发现,\(b\) 数组与 \(a\) 数组一一对应。
接下来对 \(b\) 计数,使用反射容斥即可。
//Ad astra per aspera
#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=998244353;
long long inv(long long num){
long long pre=mod-2,ans=1;
while(pre){
if(pre&1){
ans=ans*num%mod;
}
num=num*num%mod;
pre>>=1;
}
return ans;
}
long long fact[10000010],invfact[10000010],sum_C[10000010];
int n,m;
void init(){
fact[0]=invfact[0]=1;
for(int i=1;i<=n;i++){
fact[i]=fact[i-1]*i%mod;
invfact[i]=invfact[i-1]*fact[i]%mod;
}
long long tmp=inv(invfact[n]);
for(int i=n;i>=1;i--){
invfact[i]=tmp*invfact[i-1]%mod;
tmp=tmp*fact[i]%mod;
}
for(int i=0;i<=n;i++){
sum_C[i]=invfact[i]*invfact[n-i]%mod*fact[n]%mod;
}
for(int i=1;i<=n;i++){
sum_C[i]=(sum_C[i-1]+sum_C[i])%mod;
}
}
long long sumC(int l,int r){
long long ans=sum_C[r];
if(l) ans=((ans-sum_C[l-1])%mod+mod)%mod;
return ans;
}
int mod_2(int num){
if(num%2==0){
return 0;
}
else{
return 1;
}
}
long long query(int l,int r){
if(n%2==0){
if(mod_2(l)==0){
l++;
}
if(mod_2(r)==0){
r--;
}
}
else{
if(mod_2(l)==1){
l++;
}
if(mod_2(r)==1){
r--;
}
}
if(r>=1+n){
r=min(r,1+n);
}
if(l<=1-n){
l=max(l,1-n);
}
int new_l=(n+l-1)/2,new_r=(n+r-1)/2;
return sumC(new_l,new_r);
}
long long query1(int l,int r){
int L=l,R=r;
long long ans=0;
bool flag=true;
while(true){
int new_L=(L-1)*2-R,new_R=(L-1)*2-L;
L=new_L;
R=new_R;
if(R<1-n){
break;
}
long long pre=query(L,R);
if(flag==true){
ans+=pre;
ans%=mod;
}
else{
ans-=pre;
ans%=mod;
}
flag=!flag;
}
return (ans%mod+mod)%mod;
}
long long query2(int l,int r){
int L=l,R=r;
long long ans=0;
bool flag=true;
while(true){
int new_L=(R+1)*2-R,new_R=(R+1)*2-L;
L=new_L;
R=new_R;
if(L>1+n){
break;
}
long long pre=query(L,R);
if(flag==true){
ans+=pre;
ans%=mod;
}
else{
ans-=pre;
ans%=mod;
}
flag=!flag;
}
return (ans%mod+mod)%mod;
}
int main(){
scanf("%d %d",&n,&m);
n--;
init();
int l_m=0,r_m=(m+1)/2;
long long ans=query(l_m,r_m);
ans-=query1(l_m,r_m);
ans-=query2(l_m,r_m);
printf("%lld",(ans%mod+mod)%mod);
return 0;
}

浙公网安备 33010602011771号