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: [1]+[2,3,1]+[2,3]. Then we could have the following sequences:

  • b=[1,1,3,2,3,1,2,3,2],
  • b=[1,1,3,2,3,1,2,2,3],
  • b=[1,1,2,3,1,3,2,2,3],
  • b=[1,1,2,3,1,3,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(1t104) — the number of test cases.

Each test case consists of two lines.

The first line of the test case contains an integer n(1n2×105) — the size of the sequence b.

The second line of test case contains n integers b1,b2,,bn(1bi109) — the sequence b itself.

It is guaranteed that the sum of n over all test cases does not exceed 2105.

Output

For each test case print on a separate line:

  • 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.
  • NO otherwise.

You can output YES and  NO in any case (for example, strings  yEsyesYes and  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: [1]+[2,3,1]+[2,3]. The sequence b: [1,1,2,3,1,3,2,2,3].

In the second case, the sequence b could be obtained from the sequence a=[12,7,5] with the following partition: [12]+[7,5]. The sequence b: [12,1,2,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: [7,8,9,10,3]. The sequence b: [5,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作为信息段的右端点,且iai1,意味着区间[iai,i]可以作为一段合法的信息,此时如果要保证以i为结尾的前缀存在合法方案,就要看看以iai1为结尾的前缀是否存在合法方案,这个值就是f(iai1),因此f(i) |=f(iai1)。同理,再考虑i作为信息段树的左端点,如果i+ain,意味着区间[i,i+ai]可以作为一段合法的信息,此时如果要保证以i+ai为结尾的前缀存在合法方案,就要看看以i1为结尾的前缀是否存在合法方案,这个值就是f(i1),因此f(i+ai) |=f(i1)

  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 @   onlyblues  阅读(117)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示