G2. Teleporters (Hard Version)

G2. Teleporters (Hard Version)

The only difference between the easy and hard versions are the locations you can teleport to.

Consider the points 0,1,,n+1 on the number line. There is a teleporter located on each of the points 1,2,,n. At point i, you can do the following:

  • Move left one unit: it costs 1 coin.
  • Move right one unit: it costs 1 coin.
  • Use a teleporter at point i, if it exists: it costs ai coins. As a result, you can choose whether to teleport to point 0 or point n+1. Once you use a teleporter, you can't use it again.

You have c coins, and you start at point 0. What's the most number of teleporters you can use?

Input

The input consists of multiple test cases. The first line contains an integer t (1t1000) — the number of test cases. The descriptions of the test cases follow.

The first line of each test case contains two integers n and c (1n2105; 1c109) — the length of the array and the number of coins you have respectively.

The following line contains n space-separated positive integers a1,a2,,an (1ai109) — the costs to use the teleporters.

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

Output

For each test case, output the maximum number of teleporters you can use.

Example

input

复制代码
10
5 6
1 1 1 1 1
8 32
100 52 13 6 9 4 100 35
1 1
5
4 5
4 3 2 1
5 9
2 3 1 4 1
5 8
2 3 1 4 1
4 3
2 3 4 1
4 9
5 4 3 3
2 14
7 5
5 600000000
500000000 400000000 300000000 200000000 100000000
复制代码

output

复制代码
2
3
0
1
3
2
1
1
2
2
复制代码

Note

In the first test case, you can move one unit to the right, use the teleporter at index 1 and teleport to point n+1, move one unit to the left and use the teleporter at index 5. You are left with 61111=2 coins, and wherever you teleport, you won't have enough coins to use another teleporter. You have used two teleporters, so the answer is two.

In the second test case, you go four units to the right and use the teleporter to go to n+1, then go three units left and use the teleporter at index 6 to go to n+1, and finally, you go left four times and use the teleporter. The total cost will be 4+6+3+4+4+9=30, and you used three teleporters.

In the third test case, you don't have enough coins to use any teleporter, so the answer is zero.

 

解题思路

  与G1. Teleporters (Easy Version)不同,当使用了某个传送器后不仅可以选择传送到下标0处,还可以传送到下标n+1处。

  很明显,如果当前在1n的某个位置(也就是不是起点0),每个传送器的代价为min(ai+i,ai+n+1i),因此为了取到最大数目的传送器就应该按照代价从小到大来选择传送器。

  问题是现在是从0点开始,因此会有贪心的思路是从1n中选择最小的ai+i所对应的下标x,然后从0走到x,再按照上面的做法来选择传送器。但这种做法是有问题的,参考下面的数据:

2 14
7 5

  按照上面贪心的思路,x=2,当从0走到x后还剩下14(5+2)=7,已经选不了下标1处的传送器了。实际上应该取x=1,然后再传送到n+1处,这样总代价就是1+7+1+5=1414,最多可以选择2个传送器。

  因此贪心是行不通的,那么就直接枚举第一次走到的下标x,此时还剩下m(ax+x),为了快速求出最多还能选择多少个传送器,我们按照之前的思路求出每个传送器的最小代价min(ai+i,ai+n+1i),然后从小到大排序,再求前缀和,那么就可以二分出来不超过m(ax+x)的最大值了。剩下的细节见注释。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 typedef pair<int, int> PII;
 6 
 7 const int N = 2e5 + 10;
 8 
 9 PII a[N];
10 LL s[N];
11 
12 void solve() {
13     int n, m;
14     scanf("%d %d", &n, &m);
15     for (int i = 1; i <= n; i++) {
16         int x;
17         scanf("%d", &x);
18         a[i] = {x + min(i, n + 1 - i), x + i};
19     }
20     sort(a + 1, a + n + 1);
21     for (int i = 1; i <= n; i++) {
22         s[i] = s[i - 1] + a[i].first;
23     }
24     int ret = 0;
25     for (int i = 1; i <= n; i++) {    // 枚举第一次到达的下标
26         if (a[i].second <= m) {    // 至少可以选择这个传送器
27             int l = 0, r = n;    // 左端点从0开始,如果最后有l=0意味着不能选择第二个传传送器
28             while (l < r) {
29                 int mid = l + r + 1 >> 1;
30                 LL t = s[mid] + a[i].second;    // 总代价
31                 if (i <= mid) t -= a[i].first;    // 选择的传送器包括了i,应该删除对于的数据
32                 if (t <= m) l = mid;
33                 else r = mid - 1;
34             }
35             ret = max(ret, l + (l < i));    // 如果l<i那么就需要额外加上i这个位置的传送器
36         }
37     }
38     printf("%d\n", ret);
39 }
40 
41 int main() {
42     int t;
43     scanf("%d", &t);
44     while (t--) {
45         solve();
46     }
47     
48     return 0;
49 }
复制代码

 

参考资料

  Codeforces Round #849 (Div. 4) Editorial:https://codeforces.com/blog/entry/112282

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