题解 CF1710C XOR Triangle
我们令 ,,。容易发现 满足 。我们考虑他们什么时候可以构成三角形。结论是:当且仅当存在其中两个数 满足 ,不满足构成三角形。下面简单说明一下。
- 充分:当 时, 与 不会同时有一位是 。所以 ,因此不满足。
- 必要:任意两个数的与都不等于 ,我们不妨三个数大小顺序 。由于 ,那么 至少有一位同时是 ,所以 。也就满足构成三角形。
于是我们考虑数位 DP。从高位到低位做,记三个变量表示当前 是否满足已填的位都与 相同的限制,再记三个变量分别表示 ,, 是否仍为 。转移是平凡的,枚举 这一位填了什么,更新上述六个变量即可。
这样做的复杂度是 。
const int N=200005;
int n,m;
char s[N];
ll dp[N][2][2][2][2][2][2];
ll dfs(int u,bool a,bool b,bool c,bool x,bool y,bool z)
{
if (u==n+1)
{
if (x&&y&&z) return 1;
return 0;
}
if (dp[u][a][b][c][x][y][z]!=-1) return dp[u][a][b][c][x][y][z];
ll res=0;
for (int i=0;i<=1;i++)
{
if (a&&i>s[u]-'0') continue;
for (int j=0;j<=1;j++)
{
if (b&&j>s[u]-'0') continue;
for (int k=0;k<=1;k++)
{
if (c&&k>s[u]-'0') continue;
res=(res+dfs(u+1,a&(s[u]-'0'==i),b&(s[u]-'0'==j),c&(s[u]-'0'==k),x|((i^j)&(j^k)),y|((i^k)&(j^k)),z|((i^k)&(j^i))))%mod;
}
}
}
dp[u][a][b][c][x][y][z]=res;
return res;
}
int main()
{
cin >> (s+1);
n=strlen(s+1);
memset(dp,-1,sizeof(dp));
cout << dfs(1,1,1,1,0,0,0);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构