ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

51nod2554 OR 三元组

2021-08-12 20:31:21  阅读:114  来源: 互联网

标签:le const int 三元组 while 51nod2554 define


51nod2554 OR 三元组

Description

给定长度为 \(n\) 的序列 \(a\),有 \(m\) 组询问,每次给定区间 \([l, r]\) 和整数 \(x\),求有多少三元组 \((i, j, k)\) 满足:

  • \(l \le i < j < k \le r\)
  • \(a_i | a_j | a_k = x\)

其中 \(x | y\) 代表按位或。

\(n, m \le 10^5, a_i, x < 2^8\)。

Solution

非常 sb 的题目。

对于每一个询问,首先求出区间内每个数出现的次数,然后子集卷积求一个 \(f(x) = \sum_{l \le i < j < k \le r} [a_i | a_j | a_k \subseteq x]\)(这里的 \(\subseteq\) 指前者为 \(1\) 的位后者均为 \(1\)),然后再 IFWT 即可得到答案序列。

时间复杂度 \(\mathcal{O}(nw + (3^8 + 2^{11})m)\),这里子集卷积暴力更优。跑得非常快。

#include <bits/stdc++.h>

using namespace std;

#define il inline
#define re register
#define rep(i, s, e) for (re int i = s; i <= e; ++i)
#define drep(i, s, e) for (re int i = s; i >= e; --i)
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)

using ll = long long;

const int N = 100000 + 10;
const int W = 256;

il int read() {
    int x = 0; bool f = true; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = false; c = getchar();}
    while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? x : -x;
}

il void FWT(ll *f, int lim, int opt) {
    for (int o = 2, k = 1; k < lim; o <<= 1, k <<= 1) {
        for (int i = 0; i < lim; i += o) {
            rep(j, 0, k - 1) f[i + j + k] += opt * f[i + j];
        }
    }
}

int n, m, a[N], sum[N][W], cnt[W];
ll f[W];

int main() {
    n = read(), m = read();
    rep(i, 1, n) {
        a[i] = read();
        rep(j, 0, W - 1) sum[i][j] = sum[i - 1][j];
        ++ sum[i][a[i]];
    }
    while (m --) {
        int l = read(), r = read(), x = read();
        rep(i, 0, W - 1) cnt[i] = sum[r][i] - sum[l - 1][i];
        rep(i, 0, W - 1) {
            f[i] = 0;
            for (int s = i; ; s = i & (s - 1)) {
                f[i] += cnt[s];
                if (!s) break;
            }
        }
        rep(i, 0, W - 1) f[i] = f[i] * (f[i] - 1) * (f[i] - 2) / 6;
        FWT(f, W, -1);
        printf("%lld\n", f[x]);
    }
    return 0;
}

标签:le,const,int,三元组,while,51nod2554,define
来源: https://www.cnblogs.com/Scintilla/p/15134517.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有