【25.10.10】模拟赛

T3

code

#include<bits/stdc++.h>
#define ll long long
#define P pair<ll,ll>
#define mkp make_pair
using namespace std;
const int N=5005;
const ll mod=998244353;
P operator * (const P &a,const P &b){
	return mkp(a.first*b.first%mod,(a.first*b.second%mod+a.second*b.first%mod)%mod);
}
P operator + (const P &a,const P &b){
	return mkp((a.first+b.first)%mod,(a.second+b.second)%mod);
}
int n;
P f[N][2],g[N][3],h[N],pw[N],ans;
int main(){
	freopen("mad.in","r",stdin);
	freopen("mad.out","w",stdout);
	cin>>n;
	pw[1]=mkp(1,0);
	for(int i=3;i<=n;i+=2)  pw[i]=pw[i-2]*mkp(2,0);
	
	//g[i][0]:还未出现无理无智 
	//g[i][1]:出现过102/201且未终止 
	//g[i][2]:已经结束最后一个无理无智 
	g[1][0]=mkp(2,2);
	for(int i=1;i<=n;i+=2){
		g[i+2][0]=g[i+2][0]+g[i][0]*mkp(1,1); //顺延
		g[i+2][1]=g[i+2][1]+g[i][0]*mkp(1,0); //变出无理无智
		g[i+2][1]=g[i+2][1]+g[i][1]*mkp(2,0); //第一和最后的无理无智之间随选
		g[i+2][2]=g[i+2][2]+g[i][0]*mkp(1,1); //变出唯一的无理无智
		g[i+2][2]=g[i+2][2]+g[i][1]*mkp(1,1); //最后一个无理无智,后者会有有贡献
		g[i+2][2]=g[i+2][2]+g[i][2]*mkp(1,1); //顺延
		h[i]=g[i][2]+mkp(2,2*i);  //补上没有无理无智的情况
	}
	
	g[2][0]=mkp(2,2);
	for(int i=2;i<=n;i+=2){
		g[i+2][0]=g[i+2][0]+g[i][0]*mkp(1,1);
		g[i+2][1]=g[i+2][1]+g[i][0]*mkp(1,0);
		g[i+2][1]=g[i+2][1]+g[i][1]*mkp(2,0);
		g[i+2][2]=g[i+2][2]+g[i][0]*mkp(1,0);
		g[i+2][2]=g[i+2][2]+g[i][1]*mkp(1,0);
		g[i+2][2]=g[i+2][2]+g[i][2]*mkp(1,0);
		h[i]=g[i][2]+mkp(2,i);
	}
	
	f[0][1]=h[0]=mkp(1,0);
	for(int i=0;i<=n;++i){
        if(i<n){ //顺延连续段
            f[i+1][0]=f[i+1][0]+f[i][0]*mkp(1,1);
            f[i+1][1]=f[i+1][1]+f[i][1]*mkp(2,0);
        }
        else ans=ans+f[i][1]; //下一个只能是x
        for(int j=i+1;j<=n+1;j++){
            int len=j-i-1;
            if(j==n+1){
                if(len&1) ans=ans+f[i][1]*pw[len];  //xx0x0x0x0+end
                else ans=ans+f[i][0]*h[len];    //00x0x0x0+end
            }
            else if(j==n){
                if(len&1) ans=ans+f[i][1]*pw[len]*mkp(2,0);  //xx0x0x0x0+x+end
                else ans=ans+f[i][0]*h[len]*mkp(2,0);    //00x0x0x0+x+end
            }
            else{
                if(len&1){  
                    f[j+1][0]=f[j+1][0]+f[i][0]*h[len]*mkp(1,2);  //00x0x0x0x00
                    f[j+1][1]=f[j+1][1]+f[i][1]*pw[len]*mkp(4,0);  //xx0x0x0x0xx
                }
                else{
                    f[j+1][0]=f[j+1][0]+f[i][1]*h[len]*mkp(1,2);  //xx0x0x0x00
                    f[j+1][1]=f[j+1][1]+f[i][0]*h[len]*mkp(4,0);  //00x0x0x0xx
                }
            }
        }
    }
	printf("%lld\n",ans.second);
	fclose(stdin);fclose(stdout);
	return 0;
}
posted @ 2025-10-28 19:24  TimeSpacerui  阅读(3)  评论(0)    收藏  举报