Codeforces Round 893 (Div. 2)--B. The Walkway(前后缀和)

There are n benches near the Main Walkway in Summer Infomatics School. These benches are numbered by integers from 1 to n in order they follow. Also there are m cookie sellers near the Walkway. The i-th (1≤i≤m) cookie sellers is located near the si-th bench.

Petya is standing in the beginning of the Walkway. He will pass near all benches starting from the 1-st bench and ending with the n-th bench. Petya passes the distance between two consecutive benches in 1 minute. He has a knapsack with an infinite amount of cookies. Petya is going to eat cookies from his knapsack and buy them from cookie sellers during the walk.

Petya eats cookies only near the benches according to the following rule: he will eat the cookie near the i-th (1≤i≤n) bench if and only if at least one of the following conditions holds:

  • There is a cookie seller near the i-th bench. Then Petya will buy a cookie from cookie seller and eat it immediately.
  • Petya has not yet eaten a cookie. Then Petya will take a cookie from his knapsack and eat it immediately.
  • At least d minutes passed since Petya ate the previous cookie. In other words, Petya has not eaten a cookie near the benches i−1,i−2,…,max(i−d+1,1). Then Petya will take a cookie from his knapsack and eat it immediately.

You may assume that Petya eats cookies instantly. Petya will not eat two or more cookies near the same bench.

You want to minimize the number of cookies Petya will eat during his walk. In order to do this, you will ask the administration of the Summer Informatics School to remove exactly one cookie seller from the Walkway before Petya starts his walk.

Please determine the minimum possible number of cookies Petya can eat after removing exactly one cookie seller. Also determine the number of cookie sellers, such that if you remove one of them, Petya will eat the minimum possible number of cookies.

Input

The first line contains a single integer t (1≤t≤10^3) — the number of test cases.

The first line of each test case contains three integers n, m and d (2≤d≤n≤10^9, 2≤m≤min(10^5,n)) — the number of benches, the number of cookie sellers and the value of parameter d from the statement, respectively.

The second line of each test case contains m integers s1,s2,…,sm (1≤si≤n) — the locations of the cookie sellers. It is guaranteed that si<si+1 for all 1≤i≤m−1

It is guaranteed that the sum of m over all test cases does not exceed 10^5.

Output

For each test case print two integers — the minimum number of cookies that Petya can eat if exactly one cookie seller is removed, and the number of cookie sellers such that if one of them is removed, Petya will eat the minimum possible number of cookies.

input

8
6 2 2
2 5
8 3 2
3 5 8
10 4 9
2 8 9 10
30 5 8
6 8 15 24 29
30 5 8
6 8 12 20 27
8 8 3
1 2 3 4 5 6 7 8
2 2 2
1 2
1000000000 3 20000000
57008429 66778899 837653445

output

3 1
4 1
4 4
6 4
5 2
7 7
1 1
51 1

题意:有n个点,m个卖饼干的商人的坐标,d表示主人公走连续d个点至少吃一次饼干,主公人吃饼干的情况有3种: 1.该点有卖饼干的人   2.此前从来没吃过饼干(暗示点1必须吃一次饼干)   3.连续d个点至少吃一次饼干,问恰好移除一个商人使得主人公吃饼干的次数最少,且有多少种选择能达到最小值。

解析:我们可以预处理从点1到第 i 个商人所需吃的饼干数量和从点 n 到第 i 个商人所需吃的饼干数量,也就是前后缀和,此后我们枚举每一个商人,将其移除,贡献变化只受 i-1 和 i+1 的商人影响,计算出移除第 i 个商人的最终饼干数,和答案取min和计数即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],l[N],r[N];
//分别表示第i个商人的位置,从1和n到第i个商人过程种所需的饼干数
void solve()
{
    int n,m,d;
    scanf("%d%d%d",&n,&m,&d);
    for(int i=1;i<=m;i++) scanf("%d",&a[i]);//输入位置
    l[1]=(a[1]-1)/d;
    l[1]+=((a[1]-1)%d!=0);//如果不是整除,那么到a[1]点还需要吃一次
    
    //特判
    if(a[1]!=1) l[1]++;//点1必须吃饼干
    else l[1]=1;

    r[m]=(n-a[m])/d+1;
    for(int i=2;i<=m;i++)//从1到第i个位置需要吃的饼干数
    {
        l[i]=l[i-1]+(a[i]-a[i-1])/d;
        l[i]+=(a[i]-a[i-1])%d!=0;
    }
    for(int i=m-1;i>=1;i--)//从n到第i个位置需要吃的饼干数
    {
        r[i]=r[i+1]+(a[i+1]-a[i])/d;
        r[i]+=(a[i+1]-a[i])%d!=0;
    }
    //为了边界方便,先算出移除第一个和最后一个的答案
    int s1=(a[2]-1)/d+((a[2]-1)%d!=0)+r[2];//去掉第一个
    int s2=(n-a[m-1])/d+l[m-1];//去掉最后一个
    int mi=min(s1,s2),cnt=0;
    for(int i=2;i<m;i++)
    {
        int sum=l[i-1]+r[i+1]-1;
        sum+=(a[i+1]-a[i-1])/d;
        sum+=(a[i+1]-a[i-1])%d!=0;
        if(sum<mi) mi=sum,cnt=1;
        else if(sum==mi) cnt++;
    }
    cnt+=(s1==mi);
    cnt+=(s2==mi);
    printf("%d %d\n",mi,cnt);
}
int main()
{
    int t=1;
    scanf("%d",&t);
    while(t--) solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值