CF1713F Lost Array 题解
题目链接
题目解法
很牛的题!!!
先考虑 对 的贡献,因为是异或,所以只要考虑奇偶性
问题可以抽象成一条路径对应 的贡献,所以是否有 的贡献看 的奇偶性
根据 定理,这个组合数是奇数当且仅当 是 的超集,等价于
令新的 (下面仍以 代指 )
接下来的我的思路就和正解不一样了
考虑 的值是 的补集的子集的 之和,这个东西看似可以还原
但有一点没考虑到:如果要还原的话, 必须是满的 的次幂项,否则前面会有
这就直接 掉了这个做法
换个角度想
限制是 ,不妨容斥 是 的超集
令 为满足 的 的异或和,即 是 的高维后缀异或和
则 不难发现为 的高维前缀异或和
把操作反过来,因为异或的和与差是一样的,所以先做一遍高维后缀异或和,在做高维前缀异或和就可以还原出 ,时间复杂度
感觉容斥直接把思路打开了
#include <bits/stdc++.h> #define F(i,x,y) for(int i=(x);i<=(y);i++) #define DF(i,x,y) for(int i=(x);i>=(y);i--) #define ms(x,y) memset(x,y,sizeof(x)) #define SZ(x) (int)x.size()-1 #define all(x) x.begin(),x.end() #define pb push_back using namespace std; typedef long long LL; typedef unsigned long long ull; typedef pair<int,int> pii; template<typename T> void chkmax(T &x,T y){ x=max(x,y);} template<typename T> void chkmin(T &x,T y){ x=min(x,y);} template<typename T> void read(T &FF){ FF=0;int RR=1;char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1; for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48; FF*=RR; } const int N=500010; int n,f[N]; int main(){ read(n); int lg=log2(n); F(i,0,n-1) read(f[i]); F(i,0,lg) F(j,0,n-1) if(j>>i&1) f[j]^=f[j-(1<<i)]; F(i,0,lg) F(j,0,n-1) if(j>>i&1) f[j-(1<<i)]^=f[j]; DF(i,n-1,0) printf("%d ",f[i]);puts(""); return 0; }
标签:
Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通