题解:P11008 『STA - R7』异或生成序列

news/2024/10/6 8:14:04

Solution

序列 \(p\)\(1\) ~ \(n\) 的排列,因此考虑搜索回溯

\(\sum n \le 2 \times 10^6\) 得知 \(O(n^2)\) 会炸,深感遗憾但仍考虑剪枝。

坚信深搜过百万的蒟蒻。。。

\(b\) 序列为长度 \(n-1\) 的序列:

{ \(b_1,b_2,b_3 \cdots b_n-1\) }

将其前面插入一个元素 \(x\) ,得到长度为 \(n\) 的序列 \(b'\)

{ \(x,b_1,b_2,b_3 \cdots b_n-1\) }

\(f(i)\) 表示原 \(b\) 序列从第 \(1\) 位到第 \(i\) 位的异或前缀和,\(f'(i)\)表示后 \(b'\) 序列从第 \(1\) 到第 \(i+1\) 位的异或前缀和,则有:

\(f'(i)=f(i)\) xor \(b'_1\)

\(b'_1\) 可行时,根据题目中异或运算性质将其做异或前缀和便得到了所要求的 \(p\) 序列,此时 \(p_i=f'(i)\) ,这样保证了 \(b_i=p_i\) \(xor\) \(p_{i+1}\)

此时有一个浅显的可行性剪枝,因为 \(1 \le f'(i) \le n\) , 所以当存在一个 \(b'_1\) 使任意一个\(f'(i)\) 满足如下条件时,此时序列 \(b'\) 第一个数字不可行 。:

\(f'(i)\) = \(f(i)\) \(xor\) \(b'_1 = n+1\)\(0\)

因此可以一边输入 \(b\) 序列一边存异或前缀和,每一位筛掉一个如此的 \(b'_1\)

(这实际上把一部分不可行搜索给提前筛掉,剩下的不可行搜索仍继续判断并剪枝,这样便能大大降低复杂度,将那些把搜索代码卡到趋近 \(O(n^2)\) 的数据削弱成\(O(n \log n)\)。不写快读不加\(O2\), \(800ms\) 险胜)

综上,我们便完成(水过)了这一题。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+1;
int t,n,fl,b[N],p[N],mp[N],sum;
//mp存是否填过该数字
unordered_map<int,int> vis;
//vis存可行性,true表示不可行,map的初始化比数组稍快亿点点,不用TLE
void dfs(int x,int dep){if(x<1||x>n||mp[x])return;//可行性剪枝,当P[i]大于n 或 小于1 或 数字重复时不可行if(dep==n){//可行for(int i=1;i<n;++i)printf("%d ",p[i]);//输出答案printf("%d\n",x);fl=0;//已经输出答案,打上标记避免再次搜索return;}p[dep]=x;//搜索回溯++mp[x];dfs(b[dep]^x,dep+1);--mp[x];
}
int main() {scanf("%d",&t);while(t--){scanf("%d",&n);vis.clear();//初始化fl=1,sum=0;for(int i=1;i<n;++i){scanf("%d",b+i);sum^=b[i];//做异或前缀和++vis[sum];//剪枝:第一个数字的选择中筛掉0^sum即sum(序列p中仅有1~n,没有0)
//        	++vis[(n+1)^sum]; 剪枝:第一个数字的选择中筛掉(n+1)^sum(序列p中仅有1~n,没有n+1)
//          做其中一个剪枝就行,两个剪枝一起做速度更慢}for(int i=1;i<=n;++i){if(!fl) break;//如果可行if(!vis[i]) dfs(i,1);//如果且尚未输出答案,搜索第一个数为i的情况}}return 0;
}

快读压行代码

加了快读的代码( \(600\)\(ms\) 险胜,压行,码风稍怪,轻喷):

#include<bits/stdc++.h>
using namespace std;
#define to(x,y) for(int x=1;x<=y;++x)
#define fr(x,y) for(int x=0;x<y;++x)inline void wrt(int x) {if (x < 0) {x = -x;putchar('-');}if (x > 9) wrt(x / 10);putchar(x % 10 + '0');}
inline int read(){int x=0,f=1;char ch=getchar();while(ch<48||ch>57){if(ch=='-')f=-1;ch=getchar();}while(ch>=48&&ch<=57)x=x*10+ch-48,ch=getchar();return x*f;}const int N=2e6+1;
int t,n,fl,b[N],p[N],mp[N],sum;
unordered_map<int,int> vis;void dfs(int x,int dep){if(x==0||x>n||mp[x])return;if(dep==n){to(i,n-1)wrt(p[i]),putchar(' ');wrt(x),putchar('\n');fl=0;return;}p[dep]=x,++mp[x];dfs(b[dep]^x,dep+1);--mp[x];
}
int main() {for(t=read();t--;){vis.clear();n=read();fl=1;sum=0;to (i,n - 1)b[i]=read(),sum^=b[i],++vis[sum];to(i,n){if(!fl)break;if(!vis[i]){dfs(i,1);}}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/68241.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Cisco Firepower 4100 Series FTD Software 7.6.0 ASA Software 9.22.1

Cisco Firepower 4100 Series FTD Software 7.6.0 & ASA Software 9.22.1Cisco Firepower 4100 Series FTD Software 7.6.0 & ASA Software 9.22.1 Firepower Threat Defense (FTD) Software - 思科防火墙系统软件 请访问原文链接:https://sysin.org/blog/cisco-firep…

Cisco Firepower 9300 Series FTD Software 7.6.0 ASA Software 9.22.1

Cisco Firepower 9300 Series FTD Software 7.6.0 & ASA Software 9.22.1Cisco Firepower 9300 Series FTD Software 7.6.0 & ASA Software 9.22.1 Firepower Threat Defense (FTD) Software - 思科防火墙系统软件 请访问原文链接:https://sysin.org/blog/cisco-firep…

读数据湖仓08数据架构的演化

读数据湖仓08数据架构的演化1. 数据目录 1.1. 需要将分析基础设施放置在数据目录(Data Catalogue)的结构中1.1.1. 元数据1.1.2. 数据模型1.1.3. 本体1.1.4. 分类标准1.2. 数据目录类似于图书馆的图书检索目录1.2.1. 先通过图书馆的图书检索目录进行查找,以便快速找到所需的图书…

VUE2常见问题以及解决方案汇总,vue+element ui 问题以及解决方案汇总(不断更新中)

解决vue项目中 el-table 的 @row-click 事件与行内点击事件冲突,点击事件不生效(表格行点击事件和行内元素点击事件冲突)需要阻止事件冒泡 问题描述 1.点击列的编辑按钮,会触发按钮本身事件,同时会触发行点击事件 2.点击列的元素,会触发本身事件,同时会触发行点击事件 需…

1分钟了解什么是docker和docker-compose?前后端必知必会技能GET啦

@目录前情提要Docker定义:主要功能:命令示例:其他Docker Compose定义:我为什么使用它?主要功能:命令示例:主要区别配置文件:命令行操作:依赖关系管理:实际应用场景单个服务:多服务应用:总结结语欢迎路过的小哥哥小姐姐们提出更好的意见哇~~ 前情提要 本文非常简短,如果需要详…

VUE2常见问题以及解决方案汇总(不断更新中)

vue子组件传递数据给父组件 子组件可以使用 $emit 向父组件传递数据。父组件监听这个事件,并在事件触发时接收数据。 上代码 子组件 (Child.vue) <template><button @click="sendDataToParent">Send Data to Parent</button> </template>&l…

1分钟搞懂K8S中的NodeSelector

@目录NodeSelector是什么?为什么使用NodeSelector?怎么用NodeSelector?POD配置示例yaml配置示例如何知道K8S上面有哪些节点,每个节点都有什么信息呢?1. 使用kubectl命令行工具查看所有节点及其标签2. 使用kubectl命令行工具查看特定节点的标签代码举例常见的NodeSelector节…

谷歌浏览器调试技巧

谷歌浏览器断点调试# “资源(Sources)”面板# 进入浏览器,点击F12,进入调试面板,点击source 切换按钮 会打开文件列表的选项卡。资源(Sources)面板包含三个部分:文件导航(File Navigator) 区域列出了 HTML、JavaScript、CSS 和包括图片在内的其他依附于此页面的文件。…