Adventure Time URAL - 2024

‘Here’s for you!’ shouted Finn fighting the Shadow Guardians. ‘Jake! Collect the Darkness Rocks and let’s run from here!’

Jake would have been glad to finish as soon as possible, because it was wet and sad in the Dangerous Cave, but it was not so easy to gather Rocks. So he called BMO and asked him to help with choosing an optimal set of Rocks. Jake told BMO that there were n Rocks in the Cave, and they were numbered with different integers from 1 to n. Each Rock was painted one of 26 colors. Jake also reminded BMO of Princess Bubblegum’s warning: there should be at most k Rocks of pairwise different colors among the Rocks taken from the Cave. Only a set of Rocks with this property is safe. If one takes an unsafe set of Rocks from the Cave, Cosmic Evil will be awakened! Of course, Jake doesn’t want to awaken the Evil, but he wants to take as many Darkness Rocks from the Cave as possible. Help BMO to find the size of the largest safe set of Rocks and the number of different safe sets of this size. Two sets of Rocks are different if one of them contains a Rock with a number that is not contained in the other set.

Input

The first line contains n lowercase English letters (1 ≤ n ≤ 10 5); each letter denotes the color of a Rock. In the second line you are given the integer k (1 ≤ k≤ 26).

Output

Output two integers separated with a space: the size of the largest safe set of Darkness Rocks and the number of different safe sets of this size.

Example

inputoutput
abcde
1
1 5
ababac
2

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
char a[100010];
ll x[533];
long long cc[105];
bool cmp(ll a,ll b)
{
    return a>b;
}
ll C(ll m,ll n)
{
    long long i;
    cc[0] = 1;
    for(i = 1; i <= m; i++)cc[i] = cc[i - 1] * (n - i + 1) / i;
    return cc[m];
}
ll vis[130];
int main()
{
    //cout << C(1,26)<<endl;
    ll n,i,j,w,q,e,sum, len;
    scanf("%s",a);
    len = strlen(a);
    scanf("%lld",&n);
    memset(vis,0,sizeof(vis));
    memset(x,0,sizeof(x));
    sum = 0;
    for(i=0;i<len;i++)
    {
        x[a[i]-'a']++;
        if(vis[a[i]] == 0) {vis[a[i]] = 1;sum++;}
    }
//    cout << sum << endl;
//    getchar();
    if(sum <= n) {
        printf("%lld 1\n",len);
        return 0;
    }
    sort(x,x+26,cmp);
    ll num = 0;
    for(i=0;i<n;i++)
    {
        num += x[i];
    }
    w = x[n-1];
    q = 0;e = 0;
    //cout << w << endl;
    for(i=0;i<26;i++)
    {
        if(x[i]==w) q++;
        if(x[i]>w) e++;
    }
    //cout << n - e << " " << q << endl;
    //getchar();
    ll ans = C(n-e,q);
    printf("%lld %lld\n",num, ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值