CSP-S2020 T2 动物园

CSP-S2020 T2 动物园

洛谷传送门 —— Code来自Alex_Wei

解题分析:

1. 64位的数必须开 unsigned long long \(!!!\) (下称 ULL

其实不开也没问题[doge]

2. 既然要用 ULL 的变量来存 ①个位是否为1 ②那一位\(P_j\)是否有限制,
那就必然时间\(O(n + m)\),空间\(O(1)\)

3.注意特判 \(bit = 64, n = 0\) 的状况否则会爆 ULL \((2^{64} - 1)\)
至于如何查看 ULL 可以存多少,可以运用以下代码试试。

typedef unsigned long long ull;
int main(void)
{
	printf("%llu, (ull)(-1));
	/*
		输出后记得加 1 才是 2^64 的准确数
	*/
}

剩下的看代码及注释吧

#include <cstdio>
#include <cctype> // isdigit()

#define IL inline // 快读用

typedef unsigned long long ull;

ull n, m, c, k;
ull ans, p, q, num;

IL ull read()
{
	// 这里无符号long long没有负数,只需要判断是否整数即可
    ull s = 0;
    char ch = getchar();
    while (!isdigit(ch)) {
        ch = getchar();
    }
    while (isdigit(ch)) {
        s = (s << 3) + (s << 1) + ch - '0';
        ch = getchar();
    }
    return s;
}

int main()
{
    n = read();
    m = read();
    c = read(); // 读了也没用
    k = read();
    for (int i = 1; i <= n; i ++) {
        num |= read(); // 记录 1 在某位上
    }
    for (int i = 1; i <= m; i ++) {
        p |= 1ull << read(); // 记录限制 1 的位置,1ull -> (ull)1
        q = read(); // 屁用没有
    }
    for (int i = 0; i < k; i ++) {
        ans += !((p >> i) & 1) || ((num >> i) & 1);
        // 如果当前位有 1 或者 没有限制 就可以选 2^ans 个
    }
    if (ans == 64 && !n) { // 特判 bit = 64 && n == 0 的情况
        puts("18446744073709551616");
    } else {
        printf("%llu\n", ans == 64 ? -n : (1ull << ans) - n);
        /*
        	如果这里不判 bit = 64 的状况也会爆
        	即
        	if bit == 64:
        		printf("%llu\n", -n) 此处可理解为反码
        	else:
        		printf("%llu\n", (1ull << ans) - n);
        */
    }
    return 0;
}
posted @ 2021-06-04 15:25  Haruka^  阅读(57)  评论(0)    收藏  举报