CF1614C Divan and bitwise operations

题目大意

有一个未知的序列 aa,现知道 mm 个信息,每个星信息为 l r x 的形式给出,表示区间 [l,r][l,r] 的按位或为 xx,保证 aa 中每一个数都被包含在区间 [l,r][l,r] 至少一次。

请输出序列 aa 的所有子序列的异或和 mod(109+7)\bmod (10^9+7)

TT 组数据。

对于 100%100\% 的数据,保证 1T103,1n,m2105,1lrn,0x23011\leq T \leq 10^3,1 \leq n,m \leq 2*10^5,1 \leq l \leq r \leq n,0 \leq x \leq 2^{30}-1

解题思路

显然,我们可以得到整个序列的按位或就是所有 xx 的按位或,设为 SS

如果 SS 的第 ii 位为 00,贡献即为 00

否则总有一个 11,当中恰有一个对应贡献为 2i2^{i},总贡献为 2i×2n12^{i}\times2^{n-1}

那么 Ans=S×2n1Ans=S \times 2^{n-1}

时间复杂度 O(Tn)\mathcal O(Tn)

具体实现见代码。

CODE

#include <bits/stdc++.h>

#define int long long

using namespace std;

inline int read()
{
    int s = 0, w = 1;
    char c = getchar();
    for (; !isdigit(c); c = getchar())
        if (c == '-')
            w = -1;
    for (; isdigit(c); c = getchar())
        s = (s << 1) + (s << 3) + (c ^ 48);
    return s * w;
}

const int mod = 1e9 + 7;

inline int qpow(int x, int y)
{
    int res = 1;
    while (y)
    {
        if (y & 1)
            res = res * x % mod;
        x = x * x % mod;
        y >>= 1;
    }
    return res;
}

int T, n, m;

signed main()
{
    T = read();
    while (T--)
    {
        n = read(), m = read();
        int ans = 0;
        while (m--)
        {
            read(), read();
            ans = ans | read();
        }
        ans = ans * qpow(2, n - 1) % mod;
        printf("%lld\n", ans);
    }
    return 0;
}
posted @ 2021-11-28 13:24  蒟蒻orz  阅读(7)  评论(0)    收藏  举报  来源