『位运算·枚举』「四校联考」最大值

    xiaoxiao2022-07-14  169

    题解

    这道题的题解妙啊…

    显然从高位进行枚举,能选则选,这一点是很容易想到的。关键在于如何判断。

    显然,如果存在这个数是小于等于任意一个 R [ i ] R[i] R[i]的,相当于在任何一个区间都是不受约束的,可以取;至于对后面的影响,我们只需要让左右区间都减去这一个选取的数即可。

    如果存在大于 R [ i ] R[i] R[i]的,显然这一个数是没有用的;我们需要对 L [ i ] > = L[i]>= L[i]>=这个数的区间减去这个数,这样我们就可以将 a n d and and转化成了一个可以直接枚举的问题。

    代码如下:

    #include <cstdio> #include <iostream> #include <cmath> #define int long long using namespace std; int n; int ans = 0; int L[1000000]; int R[1000000]; inline int read(void) { int s = 0, w = 1;char c = getchar(); while (c < '0' || c > '9') { if (c == '-') w = -1; c = getchar();} while (c >= '0' && c <= '9') s = s*10+c-48, c = getchar(); return w * s; } signed main(void) { freopen("max.in","r",stdin); freopen("max.out","w",stdout); int n = read(); for (int i=1;i<=n;++i) L[i] = read(), R[i]= read(); for (int i=63;i>=0;--i) { bool flag = 1; int p = pow(2,i); for (int j=1;j<=n;++j) if (R[j] - p < 0) flag = 0; if (flag) ans += p; for (int j=1;j<=n;++j) if (flag || L[j] - p >= 0) L[j] -= p, R[j] -= p; } cout<<ans<<endl; return 0; }
    最新回复(0)