AGC014-F Strange Sorting
题意
\(n\)-排列,反复进行:将序列中为前缀最大值的数全部移动到序列末(两种数不改变相对位置),问经过多少次后第一次全部升序排列
做法
定义:用high表示为前缀最大值,low则反之
考虑忽略\(1\),那么\([2,n]\)相对排好序后,假设用了\(T\)次,如果\(1\)在首,则答案为\(T\),否则还要在进行一次,为\(T+1\)
检查答案是\(T\)还是\(T + 1\)? \(T = 0\)的情况非常简单
假设\(T> 0\),并考虑\(T − 1\)运算后序列的状态
令\(f\)为在\(T-1\)运算之后,在\([2,n]\)在序列中首先出现的整数。通过\(T\)的定义,我们可以证明\(f> 2\)(否则,要么\([2,n]\)在\(T-1\)运算中排序,要么再操作一下也排不好)。可以看到,在\(T − 1\)次后,如果\(1\)出现在\(f\)和\(2\)之间,则答案为\(T\),否则为\(T + 1\)
结论1:\(f\)不会出现其不在第一个位置且为high的情况
证明:考虑反证
第一个数\(y\)为high,\(y<f\)
当它们同时为high或low,相对位置不变
否则只可能\(y=low,f=high\),相对位置还是不变
结论2:
定义循环序列\((a, b, c) = (b, c, a) = (c, a, b)\)
则\(1, 2, f\)在前\(T - 1\)次组成的(关于它们位置的)循环序列不会变
证明:
\((1)\)如果\(1\)是第一个元素(这里指的不是相对顺序,就是指排在序列首)
\(~~~(i)\)如果\(2\)是第二个元素,那么\(1, 2\)是high, f是low
\(~~~(ii)\)如果\(f\)是第二个元素,那么\(1, f\)是high, 2是low
\(~~~(iii)\)否则2, f都是low
\((2)\)如果\(2\)是第一个元素,那么\(2\)是high,\(1\)和\(f\)是low
\((3)\)如果\(f\)是第一个元素,那么f是high,\(1\)和\(2\)是low
\((4)\)否则\(1, 2, f\)都是low
考虑\([i,n]\),令\(T_i\)为对序列进行排序所需的操作数。
令\(f_i\)为\(T_i − 1\)次操作后的第一个整数,考虑整数\([i,n]\)。(如果\(T_i = 0\),\(f_i\)是不确定的)。
令\(q_i\)为\(i\)在初始序列中的位置(即\(p_{q_i}= i\))。然后,我们按\(i = N,N − 1…1\)的顺序计算值\(T_i,f_i\),答案为\(T_1\)。当\(i <N\)时,可以按以下方式计算值:
- 如果\(T_{i + 1} = 0\),
\((1)\)如果\(q_i> q_{i + 1}\),则\(T_i = 1\),\(f_i = i + 1\)
\((2)\)否则,\(T_i = 0\),\(f_i\)未定义。 - 除此以外,
\((1)\)如果\(q_{f_{i + 1}}\),\(q_i\),\(q_{i+1}\)处于此循环顺序,则\(T_i = T_{i + 1}\)和\(f_i = f_{i +1}\)。
\((2)\)否则,\(T_i = T_{i + 1} +1\)和\(f_i = i + 1\)
题外话
题解的搬运工...
code(wxh)
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std;
typedef long long LL;
typedef pair < int, int > pa;
inline int read()
{
int sc = 0, f = 1; char ch = getchar();
while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
return sc * f;
}
const int MAXN = 200020;
int q[MAXN], p[MAXN], n, T[MAXN], f[MAXN];
int main()
{
#ifdef wxh010910
freopen( "data.in", "r", stdin );
#endif
n = read();
for( int i = 1 ; i <= n ; i++ ) q[ p[ i ] = read() ] = i;
for( int i = n - 1 ; i ; i-- )
{
if( !T[ i + 1 ] )
{
if( q[ i ] > q[ i + 1 ] ) T[ i ] = 1, f[ i ] = i + 1;
else T[ i ] = 0;
}
else
{
int cnt = 0;
cnt += q[ f[ i + 1 ] ] < q[ i ];
cnt += q[ i ] < q[ i + 1 ];
cnt += q[ i + 1 ] < q[ f[ i + 1 ] ];
if( cnt == 2 ) T[ i ] = T[ i + 1 ], f[ i ] = f[ i + 1 ];
else T[ i ] = T[ i + 1 ] + 1, f[ i ] = i + 1;
}
}
return printf( "%d\n", T[ 1 ] ), 0;
}
AGC014-F Strange Sorting的更多相关文章
- C Strange Sorting
C. Strange Sorting time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 数论F - Strange Way to Express Integers(不互素的的中国剩余定理)
F - Strange Way to Express Integers Time Limit:1000MS Memory Limit:131072KB 64bit IO Format: ...
- agc014F Strange Sorting
这套题比较简单,以为自己能够独立A掉D和E,或许就能自己A掉F,看来还真是想多了 题意:给一个$n$的全排列,每次操作把$max(a[1],a[2],...,a[i]) = a[i]$的记为$high ...
- 2020CCPC长春F. Strange Memory
题目大意 一棵以 \(1\) 为根的 \(n(2\leq n\leq 10^5)\) 的树,每个节点 \(i\) 有权值 \(a_{i}(1\leq a_{i}\leq 10^6)\) ,求 \(\s ...
- codeforces 484C Strange Sorting Codeforces Round #276 (Div. 1) C
思路:首先 他是对1到k 元素做一次变换,然后对2到k+1个元素做一次变化....依次做完. 如果我们对1到k个元素做完一次变换后,把整个数组循环左移一个.那么第二次还是对1 到 k个元素做和第一次一 ...
- 【AtCoder】AGC014
AGC014 链接 A - Cookie Exchanges 发现两个数之间的差会逐渐缩小,所以只要不是三个数都相同,那么log次左右一定会得到答案 #include <bits/stdc++. ...
- Atcoder Grand-014 Writeup
A - Cookie Exchanges 题面 Takahashi, Aoki and Snuke love cookies. They have A, B and C cookies, respec ...
- AtCoder Grand Contest 014
AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中 ...
- A@GC*014
A@GC*014 A Cookie Exchanges 卡时跑了1s就输出-1 每次操作会使三个数的极差缩小一半,所以最多\(\log\)次之后就会出现\(A=B=C\)的情况,可以直接判掉 B Un ...
随机推荐
- Python中__init__的用法和理解
在Python中定义类经常会用到__init__函数(方法),首先需要理解的是,两个下划线开头的函数是声明该属性为私有,不能在类的外部被使用或访问.而__init__函数(方法)支持带参数类的初始化, ...
- Web自动化测试项目(七)日志
一.日志作用 调试程序 了解系统程序运行的情况,是否正常 系统程序运行故障分析与问题定位 用来做用户行为分析和数据统计 二.为项目添加日志 └── utils ├── log_utils.py └── ...
- 笔记常用Linux命令(二) 进程和端口
查看系统进程 ps:用于报告当前系统的进程状态 a:显示所有终端机下执行的程序 ps -ef/ps aux: 这两个命令都是查看当前系统正在运行进程,两者的区别是展示格式不同. 如果想要查看特定的进程 ...
- Docker Swarm 从入门到放弃
准备工作 我本机是macOS,所以我直接安装了docker desktop,其中包含了docker-machine,不用单独安装. 安装docker主机驱动 我在网上很多人提到了使用virtualbo ...
- Java8新特性一点通 | 回顾字符转日期&JoinArray使用
StringToDate日期转换 Join Array使用 StringToDate日期转换 Convert string to date in ISO8601 format 利用LocalDate. ...
- NOIP2018PJ游记
\(NOIP2018\)普及AFO记 178pt,2=,in ZJ_Hangzhou_学军中学 \(Day\) \(0\) 中午就请假回家打模板了 \(Day\) \(1\) \(A.M.8-12\) ...
- jmeter处理http请求Content-Type类型和传参方式
引言 我们在做接口测试的时候经常会忽略数据类型content-type的格式,以及参数Parameters和Body Data的区别和用途. 对于初次接触接口的同学来说,自己在发送一个http请求时, ...
- javabst1an
(单选题)下列概念中不包括任何实现,与存储空间没有任何关系的是() A)类 B)接口 C)抽象类 D)对象 正确答案为:B解析:接口是一种只含有抽象方法或常量的一种特殊的抽象类,因为接口不包括任何实现 ...
- jsp:useBean 不能编译成class或者没有class这个属性
bean.jsp <%-- JSP学习笔记 --%> <%@ page contentType="text/html;charset=UTF-8" languag ...
- (三)(2)wait/notify实现生产者-消费者模型,join方法
生产者,消费者模型 举个例子来说明,厨师,服务员,厨师做菜,服务员上菜,如果厨师没有做好菜,那么服务员就无法上菜,厨师做好了菜,然后通知服务员消费(上菜).在这个过程之中,厨师扮演的就是生产者,服务员 ...