CF1710C XOR Triangle
https://www.luogu.com.cn/problem/CF1710C
打表发现一位上 \(a\bigotimes b +b \bigotimes c \ge a \bigotimes c\) 恒成立。
那么前面的位已经满足大于了,当前位怎么填都无所谓。也就是只要有 1 位满足大于就好了。
对 3 个式子分别记录,对 \(a,b,c\) 有无顶上界记录。因为前导零无影响(见 https://www.cnblogs.com/xugangfan/p/16537535.html),所以不用记录。
枚举下就好了。
#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
int rd() {
int sum=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0') {
sum=sum*10+ch-'0'; ch=getchar();
}
return sum*f;
}
const int mod=998244353,N=(int)(2e5+5);
char s[N];
int n;
int f[N][2][2][2][2][2][2];
int dfs(int pos,bool lima,bool limb,bool limc,bool fla,bool flb,bool flc) {
if(pos==n+1) {
return fla&&flb&&flc;
}
if(~f[pos][lima][limb][limc][fla][flb][flc]) return f[pos][lima][limb][limc][fla][flb][flc];
bool mxa=lima?s[pos]:1,mxb=limb?s[pos]:1,mxc=limc?s[pos]:1;
int res=0;
for(int a=0;a<=mxa;a++) {
for(int b=0;b<=mxb;b++) {
for(int c=0;c<=mxc;c++) {
bool x=(a^b),y=(a^c),z=(b^c);
res=(res+dfs(pos+1,lima&(a==mxa),limb&(b==mxb),limc&(c==mxc),fla|(x+y>z),flb|(x+z>y),flc|(y+z>x)))%mod;
}
}
}
return f[pos][lima][limb][limc][fla][flb][flc]=res;
}
signed main() {
memset(f,-1,sizeof(f));
scanf("%s",s+1); n=strlen(s+1);
for(int i=1;i<=n;i++) s[i]-='0';
printf("%lld",dfs(1,1,1,1,0,0,0));
return 0;
}