• 【luogu CF1710C】XOR Triangle(数位DP)


    XOR Triangle

    题目链接:luogu CF1710C

    题目大意

    给你一个数 n,要你求有多少个满足条件的 a,b,c 使得它们两两异或得到的三个值可以得到一个非退化三角形。
    其中 a,b,c 值域在 0~n 之间。

    思路

    考虑要满足三个数任意放要:
    a ⊕ b + a ⊕ c > b ⊕ c a\oplus b+a\oplus c>b\oplus c ab+ac>bc

    然后考虑一下 a ⊕ b + a ⊕ c a\oplus b+a\oplus c ab+ac 的范围,发现肯定是 ⩾ b ⊕ c \geqslant b\oplus c bc
    小证明:
    x ⊕ y ⩽ x + y x\oplus y\leqslant x+y xyx+y
    a ⊕ b + a ⊕ c ⩾ a ⊕ b ⊕ a ⊕ c ⩾ b ⊕ c a\oplus b+a\oplus c\geqslant a\oplus b\oplus a\oplus c\geqslant b\oplus c ab+acabacbc

    所以我们对于每一位,就看顶上或者没顶上,然后是否出现大于的位。(前面的肯定是等于因为如果小于没必要看)
    所以直接数位 DP 即可。

    代码

    #include
    #include
    #define ll long long
    #define mo 998244353
    
    using namespace std;
    
    const int N = 2e5 + 100;
    char s[N];
    int n;
    ll f[N][2][2][2][2][2][2];
    
    ll dfs(int now, bool d1, bool d2, bool d3, bool ok1, bool ok2, bool ok3) {
    	if (now > n) return ok1 && ok2 && ok3;
    	if (f[now][d1][d2][d3][ok1][ok2][ok3] != -1) return f[now][d1][d2][d3][ok1][ok2][ok3];
    	ll re = 0;
    	for (int c1 = 0; c1 <= (d1 ? s[now] - '0' : 1); c1++) 
    	for (int c2 = 0; c2 <= (d2 ? s[now] - '0' : 1); c2++) 
    	for (int c3 = 0; c3 <= (d3 ? s[now] - '0' : 1); c3++) {
    		bool d1_ = d1 & (c1 == s[now] - '0'), d2_ = d2 & (c2 == s[now] - '0'), d3_ = d3 & (c3 == s[now] - '0');
    		bool ok1_ = ok1 | ((c1 ^ c2) + (c1 ^ c3) > (c2 ^ c3));
    		bool ok2_ = ok2 | ((c1 ^ c2) + (c2 ^ c3) > (c1 ^ c3));
    		bool ok3_ = ok3 | ((c1 ^ c3) + (c2 ^ c3) > (c1 ^ c2));
    		(re += dfs(now + 1, d1_, d2_, d3_, ok1_, ok2_, ok3_)) %= mo;
    	}
    	return f[now][d1][d2][d3][ok1][ok2][ok3] = re;
    }
    
    int main() {
    	scanf("%s", s + 1);
    	n = strlen(s + 1);
    	
    	for (int i = 1; i <= n; i++)
    		for (int d1 = 0; d1 <= 1; d1++) for (int d2 = 0; d2 <= 1; d2++) for (int d3 = 0; d3 <= 1; d3++)
    			for (int ok1 = 0; ok1 <= 1; ok1++) for (int ok2 = 0; ok2 <= 1; ok2++) for (int ok3 = 0; ok3 <= 1; ok3++)
    				f[i][d1][d2][d3][ok1][ok2][ok3] = -1;
    	printf("%lld", dfs(1, 1, 1, 1, 0, 0, 0));
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    Linux(CentOS7)下载并安装Python 3教程及创建虚拟环境
    教培机构如何抢占招生市场
    图解LeetCode——895. 最大频率栈(难度:困难)
    MSSQL注入 — 反弹注入
    01.OpenWrt-写在前面
    【专精特新周报】北交所IPO受理现小高潮,上周共受理59家企业,七成为专精特新;朗鸿科技二度上会,顺利过会...
    STM32 | 库函数与寄存器开发区别及LED等和按键源码(第三天)
    手把手教你实战TDD
    pytorch代码实现之Partial Convolution (PConv卷积)
    Vue2 router详解
  • 原文地址:https://blog.csdn.net/weixin_43346722/article/details/126335897