E. Sending a Sequence Over the Network

E. Sending a Sequence Over the Network

The sequence $a$ is sent over the network as follows:

  1. sequence $a$ is split into segments (each element of the sequence belongs to exactly one segment, each segment is $a$ group of consecutive elements of sequence);
  2. for each segment, its length is written next to it, either to the left of it or to the right of it;
  3. the resulting sequence $b$ is sent over the network.

For example, we needed to send the sequence $a=[1,2,3,1,2,3]$. Suppose it was split into segments as follows: $[{\color{Red} 1}]+[{\color{Blue} {2,3,1}}]+[{\color{Green} {2,3}}]$. Then we could have the following sequences:

  • $b=[1,{\color{Red}1},3,{\color{Blue}{2,3,1}},{\color{Green}{2,3}},2]$,
  • $b=[{\color{Red}1},1,3,{\color{Blue}{2,3,1}},2,{\color{Green}{2,3}}]$,
  • $b=[{\color{Red}1},1,{\color{Blue}{2,3,1}},3,2,{\color{Green}{2,3}}]$,
  • $b=[{\color{Red}1},1,{\color{Blue}{2,3,1}},3,{\color{Green}{2,3}},2]$.

If a different segmentation had been used, the sent sequence might have been different.

The sequence $b$ is given. Could the sequence $b$ be sent over the network? In other words, is there such a sequence $a$ that converting $a$ to send it over the network could result in $a$ sequence $b$?

Input

The first line of input data contains a single integer $t (1 \leq t \leq {10}^{4})$ — the number of test cases.

Each test case consists of two lines.

The first line of the test case contains an integer $n (1 \leq n \leq 2 \times {10}^{5})$ — the size of the sequence $b$.

The second line of test case contains $n$ integers $b_1,b_2, \dots ,b_n (1 \leq b_i \leq {10}^{9})$ — the sequence $b$ itself.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot {10}^{5}$.

Output

For each test case print on a separate line:

  • $\text{YES}$ if sequence $b$ could be sent over the network, that is, if sequence $b$ could be obtained from some sequence $a$ to send $a$ over the network.
  • $\text{NO}$ otherwise.

You can output $\text{YES}$ and  $\text{NO}$ in any case (for example, strings  $\text{yEs}$,  $\text{yes}$,  $\text{Yes}$ and  $\text{YES}$ will be recognized as positive response).

Example

input

7
9
1 1 2 3 1 3 2 2 3
5
12 1 2 7 5
6
5 7 8 9 10 3
4
4 8 6 2
2
3 1
10
4 6 2 1 9 4 9 3 4 2
1
1

output

YES
YES
YES
NO
YES
YES
NO

Note

In the first case, the sequence $b$ could be obtained from the sequence $a=[1,2,3,1,2,3]$ with the following partition: $[{\color{Red} 1}]+[{\color{Blue} {2,3,1}}]+[{\color{Green} {2,3}}]$. The sequence $b$: $[{\color{Red} 1},1,{\color{Blue} {2,3,1}},3,2,{\color{Green} {2,3}}]$.

In the second case, the sequence $b$ could be obtained from the sequence $a=[12,7,5]$ with the following partition: $[{\color{Red} {12}}]+[{\color{Green} {7,5}}]$. The sequence $b$: $[{\color{Red} {12}},1,2,{\color{Green} {7,5}}]$.

In the third case, the sequence $b$ could be obtained from the sequence $a=[7,8,9,10,3]$ with the following partition: $[{\color{Red} {7,8,9,10,3}}]$. The sequence $b$: $[5,{\color{Red} {7,8,9,10,3}}]$.

In the fourth case, there is no sequence $a$ such that changing a for transmission over the network could produce a sequence $b$.

 

解题思路

  写这题的时候完全没想到是动态规划。

  定义状态$f(i)$表示所有以$i$为结尾的前缀合法方案的集合,如果存在合法方案的话那么$f(i) = true$,否则$f(i) = false$。

  考虑每一个位置$i$作为信息码的情况,如果下标$i$作为信息段的右端点,且$i - a_i \geq 1$,意味着区间$[i  - a_i, i]$可以作为一段合法的信息,此时如果要保证以$i$为结尾的前缀存在合法方案,就要看看以$i - a_i - 1$为结尾的前缀是否存在合法方案,这个值就是$f(i - a_i - 1)$,因此$f(i) ~|= f(i - a_i - 1)$。同理,再考虑$i$作为信息段树的左端点,如果$i + a_i \leq n$,意味着区间$[i, i + a_i]$可以作为一段合法的信息,此时如果要保证以$i + a_i$为结尾的前缀存在合法方案,就要看看以$i - 1$为结尾的前缀是否存在合法方案,这个值就是$f(i - 1)$,因此$f(i + a_i) ~|= f(i - 1)$。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 
 6 int a[N];
 7 bool f[N];
 8 
 9 void solve() {
10     int n;
11     scanf("%d", &n);
12     for (int i = 1; i <= n; i++) {
13         scanf("%d", a + i);
14     }
15     memset(f, 0, sizeof(f));
16     f[0] = true;
17     for (int i = 1; i <= n; i++) {
18         if (i - a[i] - 1 >= 0) f[i] |= f[i - a[i] - 1];
19         if (i + a[i] <= n) f[i + a[i]] |= f[i - 1];
20     }
21     printf("%s\n", f[n] ? "YES" : "NO");
22 }
23 
24 int main() {
25     int t;
26     scanf("%d", &t);
27     while (t--) {
28         solve();
29     }
30     
31     return 0;
32 }

 

参考资料

  Codeforces Round #826 (Div. 3) Editorial:https://codeforces.com/blog/entry/107908

posted @ 2022-10-13 12:01  onlyblues  阅读(111)  评论(0编辑  收藏  举报
Web Analytics