P10033 题解
不喜欢特判?不喜欢分讨?不喜欢被卡 corner?不喜欢证明?不喜欢动脑子?
那就看这篇题解!
感性思路
首先感性地感受一下题目宽泛的限制条件题解区各种花式的构造方法就不难想出,符合条件的序列实在很多,那不是随便构造?但是随便上随机化还是很容易被卡而且常数太大,又不想写屎山分讨被 corner 卡到心态爆炸,怎么办!
爆搜!直接每一位枚举 \([1, n]\),先不说枚举到一个合法解的复杂度,朴素地检查需要把序列每一位都搜完,并且光检查就要 \(O(n^2)\)。我们需要将序列合法条件进行转换,最好做到若一位填的不合法立刻剪枝,就有希望很对!
首先 \(\sum\limits_{i=l}^{r} a_i = \sum\limits_{i=l}^{r} p_i\) 容易转换成 \(\sum\limits_{i=l}^{r} (a_i - p_i) = 0\),令 \(b_i = a_i - p_i\),那么这个条件就再次转换为序列 \(b\) 的前缀和序列没有两项是相同的(注意也不能为 0)。那么搜索的时候再记一个参数表示当前 \(a_i-p_i\) 的前缀和即可。注意出题人卡了一个 \(n \log n\),于是要用 unordered_set 检查。
理性证明
刚才只是感性理解了一下时间和做法,实际上这个时间是可以被证明的!
首先不难发现每次检查的都是一个前缀,那么也就是说如果前 \(i\) 个数合法,第 \(i + 1\) 个数没有冲突,那么前 \(i + 1\) 个数合法。搜索产生回溯当且仅当第 \(i + 1\) 个数与任意一个前缀都冲突。而随着 \(n\) 增大,前缀和的产生的值域范围也是非常大的,也就是不满的。可以证明 \(n\) 大于一个定值是一定不会产生回溯的。只有经过特殊构造的 \(n\) 很小的时候才会产生回溯。但是还有一个问题,无解会将搜索跑满,那时间复杂度就不对了?但注意无解是强于存在回溯的,也就是值域要求更加窄。可以证明,当且仅当 \(n=2\) 时才会产生无解。
还有一个好玩的性质,只要有解,那么必定能构造出一组使得 \(\forall p_i \leq 4\)。综上所述,可以认为时间复杂度最坏为 \(O(Vn)\),其中 \(V\) 为构造一组合法的 \(p\) 要用到的最大的 \(p_i\),最大为常数 4。复杂度正确。
实现代码
#include <iostream>
#include <unordered_set>
using namespace std;
typedef long long ll;
int uread() {
char c = getchar();
while (c < '0' || c > '9') {
c = getchar();
}
int num = 0;
while (c >= '0' && c <= '9') {
num = (num << 1) + (num << 3) + (c ^ 48);
c = getchar();
}
return num;
}
const int N = 1e6 + 1;
int n;
int a[N], b[N];
unordered_set<ll> st;
bool dfs(int pos, ll sum) {
if (pos == n + 1) {
return true;
}
for (int i = 1; i <= n; ++i) {
if (a[pos] == i) {
continue;
}
ll now = sum + a[pos] - i;
if (st.count(now)) {
continue;
}
st.insert(now);
b[pos] = i;
if (dfs(pos + 1, now)) {
return true;
}
st.erase(now);
}
return false;
}
void solve() {
n = uread();
for (int i = 1; i <= n; ++i) {
a[i] = uread();
}
st.clear(); st.insert(0ll);
if (!dfs(1, 0ll)) {//或直接特判 n == 2
puts("-1");
return ;
}
for (int i = 1; i <= n; ++i) {
printf("%d ", b[i]);
}
putchar('\n');
}
int main(int argc, const char * argv[]) {
int T = uread();
while (T--) {
solve();
}
return 0;
}
P10033 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
- JSOI2016R3 瞎BB题解
题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...
随机推荐
- 一、swift对象存储环境搭建
系列导航 一.swift对象存储环境搭建 二.swift添加存储策略 三.swift大对象--动态大对象 四.swift大对象--静态态大对象 五.java操作swift对象存储(官网样例) 六.ja ...
- 扒一扒爱奇艺影视剧新功能——AI识别、GIF动画生成、画面截图涂鸦
AI 识别 点击画面中的 右侧出现 查看详情 GIF动画生成 点击画面中的 生成GIF动画 画面截图涂鸦 截图 涂鸦
- Liunx常用操作(四)-快速清空文件内容的方法(baseshell与vim)
一.baseshell下操作 1. $ : > filename #其中的 : 是一个占位符, 不产生任何输出. 2. $ > filename 3. $ echo "" ...
- CoinBase是什么?
什么是CoinBase交易? 比特币区块链上的每个区块中都会包含一个或者多个交易(transaction),其中第一个交易就叫做CoinBase交易. 什么是CoinBase交易? CoinBase交 ...
- 基于java+springboot的求职招聘网站-求职招聘管理系统
该系统是基于java+springboot开发的求职招聘网站.网上招聘管理系统.网上人才招聘系统.毕业生求职招聘系统.大学生求职招聘系统.校园招聘系统.企业招聘系统.是给师弟开发的毕业设计.大家学习过 ...
- 【滤波】Kalman Filter
from: 卡尔曼滤波教程 (kalmanfilter.net) 总览 关于本教程 关于作者 关于卡尔曼滤波 为什么需要预测算法 卡尔曼滤波简介 必要的背景知识 均值和期望 方差和标准差 正态分布 随 ...
- vscode - Prettier插件 统一代码风格规范,保存自动格式化代码
安装 Prettier - Code formatter prettier安装完毕,使用shift+alt+f就可格式化代码. 如果需要自动保存,要在系统设置中增加"editor.forma ...
- Redis-键
- Go-单链表-栈和队列
package main import ( "errors" "fmt" "log" ) // 单链表 // 特征: // 1. 每个节点都 ...
- [转帖]备份与恢复工具 BR 简介
https://docs.pingcap.com/zh/tidb/v4.0/backup-and-restore-tool BR 全称为 Backup & Restore,是 TiDB 分布式 ...