题解 CF1713F【Lost Array】
欣赏:杨辉三角模 2。
纪念独立做出的第一道 *2900。人类智慧找规律做法。
problem
一个
solution
手算一下
1111111111111111
0101010101010101
0011001100110011
0001000100010001
0000111100001111
0000010100000101
0000001100000011
0000000100000001
0000000011111111
0000000001010101
0000000000110011
0000000000010001
0000000000001111
0000000000000101
0000000000000011
0000000000000001
我们知道这个是组合数对 2 取模后的表,我们不关注这个。只看这个表,它有如下性质:
- 若
,将系数矩阵划分成四份,其中左下角为空,其它三份完全一致。 - 对于这其它的三份,它们也有如此的性质。
- 重标号:从右往左数
,从上往下数 。
考虑消元法求解这个问题。考虑
若
- 用下面的
行异或上面的 行,因为左下角是空的,所以异或后上面 行只剩下 的数字,可以递归求解。 - 消去左边刚刚求过的部分,对
这一部分用刚刚说的方法做。
考虑怎么消元:直接求是
所以总的时间复杂度是
code
点击查看代码
#include <cstdio>
#include <vector>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long LL;
int n,ret[1<<19],lg[1<<19];
vector<int> reduce(int L,int R,int x,int y){
if(L==R) return {x<=L&&L<=y?ret[L]:0};
int mid=(L+R)>>1;
vector<int> up=reduce(L,mid,x,y),down=reduce(mid+1,R,x,y),ans={};
int len=R-L+1;
for(int i=0;i<len/2;i++) ans.push_back(up[i]^down[i]);
for(int i=0;i<len/2;i++) ans.push_back(down[i]);
return ans;
}
void calc(vector<int> val,int L,int R){
// printf("calc(%d,%d)\n",L,R);
// assert(val.size()==R-L+1);
// printf("{");
// for(int x: val) printf("%d,",x);
// printf("}\n");
if(L==R) return void(ret[L]=val.front());
int mid=(L+R)>>1;//[L,mid],[mid+1,R]
int len=R-L+1;
vector<int> down={};
for(int i=len/2;i<len;i++) down.push_back(val[i]);
calc(down,mid+1,R);
vector<int> up={};
for(int i=0;i<len/2;i++) up.push_back(val[i]^val[i+len/2]);
calc(up,L,mid);
}
void solve(vector<int> val,int L,int R){
// printf("solve([%d,%d])\n",L,R);
// assert(val.size()==R-L+1);
// printf("{");
// for(int x: val) printf("%d,",x);
// printf("}\n");
int k=1<<lg[R-L+1],len=R-L+1;
if(R-L+1==k) return calc(val,L,R);
vector<int> sub={};
for(int i=k;i<len;i++) sub.push_back(val[i-k]^val[i]);
solve(sub,L,L+len-k-1);
vector<int> rec=reduce(L+len-k-k,L+len-k-1,L,L+len-k-1);
// printf("rec:");
// for(int x: rec) printf("%d,",x);puts("");
for(int i=k;i<len;i++) val.pop_back();
for(int i=0;i<k;i++) val[i]^=rec[i];
calc(val,L+len-k,R);
}
int main(){
scanf("%d",&n);
lg[0]=-1; for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
vector<int> val={};
for(int i=0,x;i<n;i++) scanf("%d",&x),val.push_back(x);
solve(val,0,n-1);
for(int i=0;i<n;i++) printf("%d%c",ret[i]," \n"[i==n-1]);
return 0;
}
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/solution-CF1713F.html
分类:
solution
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】