题意

有一个序列 \(A=\{a_1, a_2, ..., a_n\}\),按如下方式构造一个 \((n + 1) \times (n + 1)\) 的矩阵 \(B\):

  • \(B_{i0}=0\)(\(0\le i\le n\));
  • \(B_{0i} = a_i\)(\(1 \le i \le n\));
  • \(B_{ij} = B_{(i - 1)j} \text{ xor } B_{i(j - 1)}\)(\(1 \le i, j \le n\))。

现在给出 \(B_{1n}, B_{2n}, ..., B_{nn}\)(也就是最后一,但是没有 \(B_{0n}\)),求出 \(A\)。

\(n \le 5 \times 10^5\)

解析

题目给出的是 \(B\) 的递推式,我们希望得到计算式,换句话说,我们希望直接得到 \(B_{in}\) 只与 \(A\) 有关的表达式。

倒过来想,考虑 \(a_i\) 对 \(B_{jn}\) 的贡献。由于是异或,\(a_i\) 只可能贡献 \(a_i\) 或 \(0\)。

那具体贡献多少?我们可以把问题具象化,\(B\) 的递推式相当于是“向左走一步或向上走一步”。那么只需要判断从 \(B_{jn}\) 走到 \(B_{0i}\) 的方案数是奇数还是偶数。这里有一个小细节——“走到 \(B_{0i}\) 就结束了,不能继续走到 \(B_{0(i-1)}\)”,这个细节相当于说最后一步一定是向上的

这样我们就可以通过组合数算出 \(B_{jn}\) 到 \(B_{0i}\) 的方案数:

\[\binom{(n - i) + (j - 1)}{j - 1}
\]

这样并不好看,我们设 \(a'_i = a_{n - i}\),\(b_i = B_{i + 1, n}\)。那么 \(a_i'\) 对 \(b_j\) 的贡献只需要看 \(\binom{i + j}{j}\) 的奇偶性。关于组合数的奇偶性,结论如下:

\(\binom ab\) 为奇数当且仅当 \(a\text{ and }b = b\)。

也就是说 \(a_i'\) 对 \(b_j\) 有贡献当且仅当 \((i + j)\text{ and }j=j\) 等价于 \(i\text{ and }j = 0\)。

\[b_j = \bigotimes_{i\text{ and }j = 0}a_i'
\]

似乎有一个做法,如果把 \(j\) 取个补集,那条件不就是 \(i\in j\)(\(i\text{ and }j = i\)),那么

\[b'_j = \bigotimes_{i \in j}a_i'
\]

这 \(b'\) 不就是 \(a'\) 做了或卷积 FWT 的结果吗?然而,由于 \(n\) 未必是 \(2\) 的整次方,\(b'_0, b'_1, ..., b_{n - 1}'\) 中有几项我们不知道。这个方法就这么废了……

我们再考虑一下 \(i\text{ and }j\) 能怎么处理——容斥?我们钦定 \(i\) 对应的二进制位全为 \(1\),即 \(i\text{ and }j = i\),记为 \(c_i\):

\[c_i = \bigotimes_{i \in j}a_j'
\]

则由容斥可得下式(容斥的正负系数在异或中没有意义)

\[b_i = \bigotimes_{j \in i}c_j
\]

唔,看起来好像没什么区别,还更麻烦了?先分析一下,由于 \(c_i\) 是计算 \(i\) 的超集的异或和,那么当 \(i \ge n\) 时,\(c_i = 0\)。于是我们只需要计算 \(c_0, c_1, ..., c_{n - 1}\),那么我们可以通过 \(b\) 计算出这些结果吗?

当然是可以的——因为这是或卷积的 fwt,计算 \(b_i\) 只需要用到 \(j \le i\) 的 \(c_j\),那么就可以通过 \(b_{0~(n-1)}\) 做一遍或卷积 fmt 求出 \(c_{0~(n-1)}\)。

最后再用完整的 \(c\) 做一遍与卷积 fmt 求得 \(a'\)。

源代码

#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAXN = (int)5e5 + 10;
int len, lg2_len;
int arr[MAXN];
void fwtOr()
{
    for (int i = 0; i <= lg2_len; ++i)
    {
        for (int j = 0; j < len; ++j)
        {
            if (j & (1 << i))
            {
                arr[j] ^= arr[j ^ (1 << i)];
            }
        }
    }
}
void fwtAnd()
{
    for (int i = 0; i <= lg2_len; ++i)
    {
        for (int j = 0; j < len; ++j)
        {
            if (j & (1 << i))
            {
                arr[j ^ (1 << i)] ^= arr[j];
            }
        }
    }
}
int main()
{
    scanf("%d", &len);
    for (int i = 0; i < len; ++i)
    {
        scanf("%d", &arr[i]);
    }
    while ((1 << lg2_len) < len)
    {
        ++lg2_len;
    }
   
    fwtOr();
    fwtAnd();
    for (int i = 1; i < len; ++i)
    {
        printf("%d ", arr[len - i]);
    }
    printf("%d\n", arr[0]);
    return 0;
}

「postOI」Lost Array的更多相关文章

  1. 「CF86D」Powerful array 解题报告

    题面 给出一个\(n\)个数组成的数列\(a\),有\(t\)次询问,每次询问为一个\([l,r]\)的区间,求区间内每种数字出现次数的平方×数字的值 的和 思路: 直接上莫队咯 然后就T了 没学过莫 ...

  2. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  3. 【微信小程序】开发实战 之 「配置项」与「逻辑层」

    微信小程序作为微信生态重要的一环,在实际生活.工作.商业中的应用越来越广泛.想学习微信小程序开发的朋友也越来越多,本文将在小程序框架的基础上就微信小程序项目开发所必需的基础知识及语法特点进行了详细总结 ...

  4. 后盾网lavarel视频项目---Laravel 安装代码智能提示扩展「laravel-ide-helper」

    后盾网lavarel视频项目---Laravel 安装代码智能提示扩展「laravel-ide-helper」 一.总结 一句话总结: laravel-ide-helper作用是:代码提示 larav ...

  5. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  6. 洛谷比赛 「EZEC」 Round 4

    洛谷比赛 「EZEC」 Round 4 T1 zrmpaul Loves Array 题目描述 小 Z 有一个下标从 \(1\) 开始并且长度为 \(n\) 的序列,初始时下标为 \(i\) 位置的数 ...

  7. 【入门必看】不理解「对象」?很可能有致命bug:简单的Python例子告诉你

    简介:越来越多的人要在学习工作中用到『编程』这个工具了,其中很大一部分人用的是Python.大部分人只是做做简单的科研计算.绘图.办公自动化或者爬虫,但-- 这就不需要理解「指针与面向对象」了吗? 在 ...

  8. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  9. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  10. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

随机推荐

  1. vue学习笔记(二) ---- vue实例的生命周期

    vue实例的生命周期 什么是生命周期:从Vue实例创建.运行.到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期! 生命周期钩子:就是生命周期事件的别名而已: 生命周期钩子 = 生命周期函 ...

  2. 【Oculus Interaction SDK】(六)实体按钮 && 按压交互

    前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...

  3. 一次生产环境CPU占用高的排查

    1. 项目背景 甲方是保密级别非常高的政府部门.所以我们全程拿不到任何测试数据,只能是自己模拟数据进行测试. 项目部署的时候,公司派了一人到甲方现场,在甲方客户全程监督下,进行部署,调试,导入数据等工 ...

  4. 最长上升子序列 II 时间复杂度(nlogn)

    题目:最长上升子序列 II 给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少. 输入格式 第一行包含整数 N. 第二行包含 N个整数,表示完整序列. 输出格式 输出一个整数,表示 ...

  5. 线程私有变量ThreadLocal详解

    本文已收录至Github,推荐阅读 Java随想录 微信公众号:Java随想录 CSDN: 码农BookSea 烈火试真金,逆境试强者.--塞内加 目录 什么是ThreadLocal ThreadLo ...

  6. 1.初识 Django

    设计模式 定义 # mysite/news/models.py from django.db import models class Reporter(models.Model): full_name ...

  7. Redis 源码解读之 expire 的时机

    Redis 源码解读之 expire 的时机 背景和问题 本文想解决的问题: redis 如何感知并触发 key 过期的? 如何防止大规模的 key 同时过期,导致 redis 主循环阻塞在清理过期 ...

  8. 10分钟学会使用 Loki 日志聚合系统

    Loki 是一个由Grafana Labs 开发的开源日志聚合系统,旨在为云原生架构提供高效的日志处理解决方案. Loki 通过使用类似 Prometheus 的标签索引机制来存储和查询日志数据,这使 ...

  9. 题解 P7623 [AHOI2021初中组] 收衣服

    我还在小学的时候以现在初中名义我大五十牛逼参加了这次,然后身败名裂死磕这道题不会,现在觉得自己好傻啊 233333 显然这是要统计每个区间的贡献,所以我们可以打出来这个暴力,统计每个区间的次数,对于 ...

  10. MySQL创建表的三种方式

    创建表的三种方式 通过create语句直接创建 语法: create [TEMPORARY] table [IF NOT EXISTS] table_name ( col_name column_de ...