好题。
一眼看上去就是数位$dp$。然后我就在想是否是红色一定有什么条件。
之后发现保证了前驱红色个数的奇偶性,然后我就想是不是红色个数的奇偶决定的。
分析了一发感觉非常有理,但是后来我发现如果是个数的话我没有加上自己,然后这个思路就被我扔了。
然后就没思路了。。。。
看了题解真的觉得自己迟钝到一定地步了。
颜色取决于$(1,1......,1)$到这个点的路径条数(虽然很好证,但是怎么想到才是关键啊)。
然后就很简单了。
条件就是$forall xi|xj==xi+xj$,即没有交集($lucas$定理)。
然后就可以数位$dp$了。
$O(T*3^k*k*logw)$。
#include <bits/stdc++.h> #define for1(a,b,i) for(int i=a;i<=b;++i) #define FOR2(a,b,i) for(int i=a;i>=b;--i) using namespace std; typedef long long ll; #define M 20 #define N 520 #define mod 998244353 int n; ll L[M],R[M]; inline void inc(int &x,int y) {x+=y,x-=x>=mod?mod:0;} struct set_ { int id[N][N]; int size,ax[N*N],ay[N*N],f[N*N]; inline void clear() { for1(1,size,i) { f[i]=0; id[ax[i]][ay[i]]=0; } size=0; } inline void add_(int x,int y,int z) { if(!id[x][y]) { id[x][y]=++size; ax[size]=x,ay[size]=y; } inc(f[id[x][y]],z); } }Y[2]; inline void turn_(int be,int &x,int &y,int z) { if(z&&!(y>>z-1&1)&&!(R[z]>>be&1)) return x=-1,void(); for1(1,n,i) if(z!=i&&!(x>>i-1&1)&&(L[i]>>be&1)) return x=-1,void(); if(z&&!(x>>z-1&1)&&!(L[z]>>be&1)) x+=1<<z-1; for1(1,n,i) if(z!=i&&!(y>>i-1&1)&&(R[i]>>be&1)) y+=1<<i-1; } int main () { //freopen("a.in","r",stdin); int Test_; scanf("%d",&Test_); while (Test_--) { scanf("%d",&n); for1(1,n,i) scanf("%lld",L+i),--L[i]; for1(1,n,i) scanf("%lld",R+i),--R[i]; int opt=0; Y[0].add_(0,0,1); FOR2(49,0,i) { FOR2(Y[opt].size,1,j) { int x=Y[opt].ax[j]; int y=Y[opt].ay[j]; int sel=Y[opt].f[j]; for1(0,n,k) { int ax=x,ay=y; turn_(i,ax,ay,k); if(ax==-1) continue; Y[opt^1].add_(ax,ay,sel); } } Y[opt].clear(); opt^=1; } int ans=0; for1(1,Y[opt].size,i) inc(ans,Y[opt].f[i]); Y[opt].clear(); printf("%d ",ans); } }