「CF1713F」 Lost Array 题解

「CF1713F」 Lost Array 题解

题意

     有一个长为 n 的数组 {a} ,把它作为方阵 b 的第零层,从第一层开始 bi,j=bi1,jbi,j1 ,直到第 n 层。现在已知每一层的最后一个位置,求构造 {a} 来还原它或说明无解。
     1n5×105

题解

     什么神仙题!!!!!1

     先由 CF 第?定律得知没有样例无解所以大概率没有无解的情况。

     那就考虑用 {a} 怎么构造 {b} 。下面是一个非常妙的转化。

     先考虑把 a 从右往左编号为 0,1,,n1 。先考虑 aibj,j 的贡献(矩阵的行也反过来编号,但列还是从上到下编号)那就是 (ij+jj)=(ij) ,由于是异或,所以我们只关心 (ij)mod2 的值。由于结论:(ij) 为奇数当且仅当 iandj=j ,其中 and 指按位与,那么我们可以发现 bj,j 其实就是 a 这里的异或超集和。结论的证明有心情再来补吧。

     同理从 bi,i 走到 b0,j (列上还是从上到下顺序编号)的方案数为 (ji) ,所以 b0,jbi,i 的子集和。

     那现在我们已经知道了 b0,j ,所以用逆子集和和逆超集和(在异或意义下也就是子集和和超集和)来还原 a 即可。

代码

查看代码
#include <bits/stdc++.h>
using namespace std;
template<typename T>void read(T &x)
{
    T f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9') {x=x*10+s-'0';s=getchar();}
    x*=f;
}
int arr[1000005];
int main() {
    #ifndef ONLINE_JUDGE
    freopen("input","r",stdin);
    freopen("output","w",stdout);
    #endif
    int n;read(n);n--;
    for(int i=0;i<=n;i++) read(arr[i]);
    int Lg=log2(n);
    for(int i=0;i<=Lg;i++) for(int j=n;j>=0;j--) if((j>>i)&1) arr[j]^=arr[j^(1<<i)];
    for(int i=0;i<=Lg;i++) for(int j=0;j<=n;j++) if(!((j>>i)&1)) arr[j]^=arr[j^(1<<i)];
    for(int i=n;i>=0;i--) printf("%d ",arr[i]);
    return 0;
}
/*
清夜无尘。月色如银。酒斟时、须满十分。浮名浮利,虚苦劳神。叹隙中驹,石中火,梦中身。
虽抱文章,开口谁亲。且陶陶、乐尽天真。几时归去,作个闲人。对一张琴,一壶酒,一溪云。
*/
posted @   Azazеl  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示