abc317f

发布时间 2023-09-05 22:44:20作者: gan_coder

abc317f

一看就是数位dp,但之前还想错了,今天课上突然想到
之前想的是怎样构造保证能够整除
但实际上将余数也设计到状态中就行

其他就是基本的数位dp

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++) //
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define ff(i,a,b) for ((i)=(a);(i)<=(b);(i)++)
#define mk(x,y) make_pair((x),(y))
#define A puts("YES")
#define B puts("NO")

using namespace std;
typedef double db;
typedef long long ll;
const ll mo=998244353;
ll f[100][8][11][11][11][8];
ll b[100],k,n,tot,d[100],r[10],a[10],rr[10],ss,ans;

void add(ll &x, ll y){
	x=(x+y)%mo;
}
bool F(ll x,ll y){
	if (x && y) return 1;
	if (!x && !y) return 1;
	return 0;
}
void solve(){
	f[tot+1][7][0][0][0][0]=1; //
	fd(i,tot,0){
		fo(s,0,7) ff(r[0],0,a[0]-1) ff(r[1],0,a[1]-1) ff(r[2],0,a[2]-1) {
			fo(sw,0,7) {
				
				if (!f[i+1][s][r[0]][r[1]][r[2]][sw]) continue;
				int temp;
				bool flag;
				fo(t,0,7) {
					temp=0;
					flag=1;
					ss=0;
					fo(j,0,2) {
						if (t&b[j]) temp^=1;
						if ((s&b[j]) && (t&b[j]) && (!d[i])) flag=0;
						if ((s&b[j]) && F(t&b[j], d[i])) ss|=b[j];
					}
					if (temp || !flag) continue;
					
					fo(j,0,2) {
						rr[j]=r[j];
						if (t&b[j]) rr[j]=(rr[j]+b[i])%a[j];
					}
					
					add(f[i][ss][rr[0]][rr[1]][rr[2]][sw|t], f[i+1][s][r[0]][r[1]][r[2]][sw]);
				}
			}
		}
	}

	fo(s,0,7) {
		add(ans, f[0][s][0][0][0][7]);
	}
}
int main()
{
//	freopen("data.in","r",stdin);

	b[0]=1;
	fo(i,1,62) b[i]=b[i-1]*2ll;
	
	scanf("%lld",&n);
	fo(i,0,2) scanf("%lld",&a[i]);
	
	k=n; tot=0;
	while (k){
		d[tot++]=k&1;
		k/=2;
	}
	solve();
	
	printf("%lld",ans);
	
	
	return 0; 

}