题意: 阅读理解题。读了三十多分钟才明白大意。
给定一个序列,问按照从 1 1 1 n n n的顺序放置这 n n n个数。
假设这 n n n个数分 k k k次放置,每次从第 n ( <mover> <munder> j = 1 </munder> i </mover> n-(\overset{i}{\underset{j=1}{\sum}} n(j=1i s [ j ] ) + 1 s[j])+1 s[j])+1开始放置 s [ i ] s[i] s[i]个数,
要求这 s [ i ] s[i] s[i]个数的范围为 [ <mover> <munder> j = 1 </munder> i 1 </mover> [\overset{i-1}{\underset{j=1}{\sum}} [j=1i1 s [ j ] + 1 , <mover> <munder> j = 1 </munder> i </mover> s[j]+1,\overset{i}{\underset{j=1}{\sum}} s[j]+1,j=1i s [ j ] ] s[j]] s[j]]

举个例子:如序列 { 4 , 5 , 6 , 7 , 2 , 3 , 1 } \{4,5,6,7,2,3,1\} {4,5,6,7,2,3,1},那么第一组为: { 1 } \{1\} {1},第二组为 { 2 , 3 } \{2,3\} {2,3},第三组为: { 4 , 5 , 6 , 7 } \{4,5,6,7\} {4,5,6,7},我们按照顺序依次在第 [ 7 , 7 ] [7,7] [7,7]放入了 1 1 1 [ 5 , 6 ] [5,6] [5,6]放入了 2 , 3 2,3 2,3 [ 1 , 4 ] [1,4] [1,4]放入了 4 , 5 , 6 , 7 4,5,6,7 4,5,6,7

题解: 可以发现对于给定序列如果是合法的,那么对于任意的 a [ i ] a [ i 1 ] 1 a[i]-a[i-1] \leq 1 a[i]a[i1]1
证明: 若存在合法的序列,其相邻的数字之差大于 1 1 1
那么必然存在有相邻的两个数 x , x + d i f , d i f > 1 x,x+dif,dif >1 x,x+dif,dif>1,其中 p o s [ x + d i f ] p o s [ x ] = 1 pos[x+dif]-pos[x]=1 pos[x+dif]pos[x]=1
首先,由于每组内是按照升序放置的,故组内不会出现相邻数字差 > 1 >1 >1的情况,故这必然存在于不同组的边界间。若两组间边界相差大于 1 1 1,即两组之间必然存在至少一个数在两组被放置后仍未被放置。
假设第一组数为 [ x , x + 1 , x + 2 , . . . y 2 ] [x,x+1,x+2,...y-2] [x,x+1,x+2,...y2],第二组数为 [ y , y + 1 , y + 2... , n ] [y,y+1,y+2...,n] [y,y+1,y+2...,n]
那么由于 y 1 y-1 y1这个数未被放置,但是按照我们的分组要求,如果实际给出序列满足上面的两组连续,则 y 1 y-1 y1必然可以使得两组数连接成为一组。那么如果真的存在如上的序列,其必然是不合法序列。


代码:

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int q[N], n;

void solve() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &q[i]);
	
	for(int i = 2; i <= n; i++)
		if(q[i] - q[i - 1] > 1) {
			puts("No");
			return ;	
		} 
	puts("Yes");
}

int main()
{
	int T = 1;
	scanf("%d", &T);
	while(T--) solve();
	
	return 0;
}