不喜欢特判?不喜欢分讨?不喜欢被卡 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 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. Spring相关原理

    Spring是什么? Spring是一个轻量级的IoC和AOP容器框架.常见的配置方式有三种:基于XML的配置.基于注解的配置.基于Java的配置. 模块分为以下:Spring Core:Spring ...

  2. vue学习笔记 十七、父子组件 ---> 子组件传值

    系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...

  3. P5733 【深基6.例1】自动修正

    1.题目介绍 2. 题解 2.1 字符串大小写转换 思路 str[i] -= 'a' -'A'; 注意这里转换方式,即减去偏移量(ASCII码表中,'a'在'A'前面,如果记不得偏移量,就直接写'a' ...

  4. 修改Keil uvison4 字体样式

    1.点击扳手配置 2.点击Colors & Fonts,选择其中的8051:Editor C Files,选择Text,点击右侧的Courier New... 3.在里面就可以调节字体了

  5. C++17 解构绑定

    在python中,加入我们有一个函数返回了两个数值,如: def getData(x, y): return x,y 那么我们在使用这个函数时只需要使用两个新变量去接收函数返回值就可以: a,b = ...

  6. 【Spring 5核心原理】1设计模式

    1.1开闭原则 开闭原则(open-closed principle,OCP)是指一个软件实体(如类,模块和函数)应该对扩展开放,对修改关闭.所谓的开闭,也正是对扩展和修改两个行为的一个原则. 强调用 ...

  7. Go-错误栈信息

    Go中错误栈信息 .\main.go:22:2: number1 declared but not used .\main.go 错误发生的文件 22:2 文件的22行第2列 number1 decl ...

  8. [转帖]Oracle安装 - shmmax和shmall设置

    https://www.cnblogs.com/ddzj01/p/16108010.html 一.概述 在Linux上安装oracle,需要对内核参数进行调整,其中有shmmax和shmall这两个参 ...

  9. [转帖]Nginx优化与防盗链

    目录 一.配置Nginx隐藏版本号 1.第一种方法修改配置文件 2.第二种方法修改源码文件,重新编译安装 二.修改Nginx用户与组 三.配置Nginx网页缓存时间 四.实现Nginx的日志分割 五. ...

  10. [转帖]kafka漏洞升级记录,基于SASL JAAS 配置和 SASL 协议,涉及版本3.4以下

    攻击者可以使用基于 SASL JAAS 配置和 SASL 协议的任意 Kafka 客户端,在对 Kafka Connect worker 创建或修改连接器时,通过构造特殊的配置,进行 JNDI 注入. ...