Output
For each query print one integer: -1 if Vova cannot complete the game or the maximum number of turns Vova can just play (make the first type turn) otherwise.
Example
inputCopy
6
15 5 3 2
15 5 4 3
15 5 2 1
15 5 5 1
16 7 5 2
20 5 7 3
outputCopy
4
-1
5
2
0
1
Note
In the first example query Vova can just play 4 turns and spend 12 units of charge and then one turn play and charge and spend 2 more units. So the remaining charge of the battery will be 1.
In the second example query Vova cannot complete the game because even if he will play and charge the battery during each turn then the charge of the laptop battery will be 0 after the last turn.
题意:给出一个游戏规则,求最多进行1操作的次数
题解:二分次数检查即可
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
int a[105];
int main()
{
int q;
scanf("%d",&q);
while(q--){
ll k,n,a,b;
scanf("%lld%lld%lld%lld",&k,&n,&a,&b);
ll L=0;
ll R=n;
ll ans=-1;
while(L<=R){
ll mid=(L+R)/2;
if(mid*a+(n-mid)*b<k){
ans=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
printf("%lld\n",ans);
}
return 0;
}
D. Candy Box (easy version)
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This problem is actually a subproblem of problem G from the same contest.
There are n candies in a candy box. The type of the i-th candy is ai (1≤ai≤n).
You have to prepare a gift using some of these candies with the following restriction: the numbers of candies of each type presented in a gift should be all distinct (i. e. for example, a gift having two candies of type 1 and two candies of type 2 is bad).
It is possible that multiple types of candies are completely absent from the gift. It is also possible that not all candies of some types will be taken to a gift.
Your task is to find out the maximum possible size of the single gift you can prepare using the candies you have.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries. Each query is represented by two lines.
The first line of each query contains one integer n (1≤n≤2⋅105) — the number of candies.
The second line of each query contains n integers a1,a2,…,an (1≤ai≤n), where ai is the type of the i-th candy in the box.
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print one integer — the maximum possible size of the single gift you can compose using candies you got in this query with the restriction described in the problem statement.
Example
inputCopy
3
8
1 4 8 4 5 6 3 8
16
2 1 3 3 4 3 4 4 1 3 2 2 2 4 1 1
9
2 2 4 4 4 7 7 7 7
outputCopy
3
10
9
Note
In the first query, you can prepare a gift with two candies of type 8 and one candy of type 5, totalling to 3 candies.
Note that this is not the only possible solution — taking two candies of type 4 and one candy of type 6 is also valid.
题意:有n个物品,每个物品的种类为ai,要求取出的每种种类的个数都不一样,求最多取出的总个数
题解:排序之后直接贪心地从多往少取即可
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
ll in[200005];
int main()
{
int q;
scanf("%d",&q);
while(q--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)in[i]=0;
for(int i=1;i<=n;i++){int w;scanf("%d",&w);in[w]++;}
sort(in+1,in+1+n);
ll ans=in[n];
ll maxx=in[n];
for(int i=n-1;i>=1;i--){
ans+=max(min(in[i],maxx-1),0ll);
maxx=min(maxx,max(min(in[i],maxx-1),0ll));
}
printf("%lld\n",ans);
}
return 0;
}
E. Subsequences (easy version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between the easy and the hard versions is constraints.
A subsequence is a string that can be derived from another string by deleting some or no symbols without changing the order of the remaining symbols. Characters to be deleted are not required to go successively, there can be any gaps between them. For example, for the string “abaca” the following strings are subsequences: “abaca”, “aba”, “aaa”, “a” and “” (empty string). But the following strings are not subsequences: “aabaca”, “cb” and “bcaa”.
You are given a string s consisting of n lowercase Latin letters.
In one move you can take any subsequence t of the given string and add it to the set S. The set S can’t contain duplicates. This move costs n−|t|, where |t| is the length of the added subsequence (i.e. the price equals to the number of the deleted characters).
Your task is to find out the minimum possible total cost to obtain a set S of size k or report that it is impossible to do so.
Input
The first line of the input contains two integers n and k (1≤n,k≤100) — the length of the string and the size of the set, correspondingly.
The second line of the input contains a string s consisting of n lowercase Latin letters.
Output
Print one integer — if it is impossible to obtain the set S of size k, print -1. Otherwise, print the minimum possible total cost to do it.
Examples
inputCopy
4 5
asdf
outputCopy
4
inputCopy
5 6
aaaaa
outputCopy
15
inputCopy
5 7
aaaaa
outputCopy
-1
inputCopy
10 100
ajihiushda
outputCopy
233
Note
In the first example we can generate S = { “asdf”, “asd”, “adf”, “asf”, “sdf” }. The cost of the first element in S is 0 and the cost of the others is 1. So the total cost of S is 4.
题意:给出一个字符串,求k个不重复的子序列,要求子序列的总长度最长
题解:dp,dp[i][j]表示到达i处,长度为j的子序列的种类数,容易得出转移方程dp[i][j]=dp[i-1][j]+dp[i-1][j-1],而这样会在当前字符之前出现过的情况下重复计算一些子序列,所以要减去dp[k-1][j-1],其中k就是当前字符在之前出现的最后位置
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
ll last[27],dp[105][105];
char ch[105];
int main()
{
ll n,k;
scanf("%lld%lld",&n,&k);
scanf("%s",ch+1);
dp[0][0]=1;
for(int i=1;i<=n;i++){
int x=ch[i]-'a';
dp[i][0]=1;
for(int j=0;j<=i;j++){
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
if(last[x])dp[i][j]-=dp[last[x]-1][j-1];
}
last[x]=i;
}
ll ans=0;
for(int i=n;i>=0;i--){
if(k>dp[n][i]){
k-=dp[n][i];
ans+=dp[n][i]*(n-i);
}
else{
ans+=k*(n-i);
printf("%lld\n",ans);
return 0;
}
}
printf("-1\n");
return 0;
}
F. Topforces Strikes Back
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One important contest will take place on the most famous programming platform (Topforces) very soon!
The authors have a pool of n problems and should choose at most three of them into this contest. The prettiness of the i-th problem is ai. The authors have to compose the most pretty contest (in other words, the cumulative prettinesses of chosen problems should be maximum possible).
But there is one important thing in the contest preparation: because of some superstitions of authors, the prettinesses of problems cannot divide each other. In other words, if the prettinesses of chosen problems are x,y,z, then x should be divisible by neither y, nor z, y should be divisible by neither x, nor z and z should be divisible by neither x, nor y. If the prettinesses of chosen problems are x and y then neither x should be divisible by y nor y should be divisible by x. Any contest composed from one problem is considered good.
Your task is to find out the maximum possible total prettiness of the contest composed of at most three problems from the given pool.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries.
The first line of the query contains one integer n (1≤n≤2⋅105) — the number of problems.
The second line of the query contains n integers a1,a2,…,an (2≤ai≤2⋅105), where ai is the prettiness of the i-th problem.
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print one integer — the maximum possible cumulative prettiness of the contest composed of at most three problems from the given pool of problems in the query.
Example
inputCopy
3
4
5 6 15 30
4
10 6 30 15
3
3 4 6
outputCopy
30
31
10
题意:给一个序列ai,取出3个数,要求这三个数不能出现ai%aj==0的情况,求三数之和的最大值
题解:排序之后暴力,加上部分判断剪枝
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
int a[200005];
int main()
{
int q;
scanf("%d",&q);
while(q--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){scanf("%d",&a[i]);}
sort(a+1,a+1+n);
int ans=a[n];
for(int i=n;i>=1;i--){
if(a[i]*3<=ans)break;
for(int j=i-1;j>=1;j--){
if(a[j]*2+a[i]<=ans)break;
if(a[i]%a[j]==0)continue;
for(int k=j-1;k>=1;k--){
if(a[k]+a[j]+a[i]<=ans)break;
if(a[j]%a[k]==0||a[i]%a[k]==0)continue;
ans=max(a[i]+a[j]+a[k],ans);
break;
}
ans=max(a[i]+a[j],ans);
while(j>=2&&a[j-1]==a[j])j--;
}
while(i>=2&&a[i-1]==a[i])i--;
}
printf("%d\n",ans);
}
return 0;
}
G. Candy Box (hard version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This problem is a version of problem D from the same contest with some additional constraints and tasks.
There are n candies in a candy box. The type of the i-th candy is ai (1≤ai≤n).
You have to prepare a gift using some of these candies with the following restriction: the numbers of candies of each type presented in a gift should be all distinct (i. e. for example, a gift having two candies of type 1 and two candies of type 2 is bad).
It is possible that multiple types of candies are completely absent from the gift. It is also possible that not all candies of some types will be taken to a gift.
You really like some of the candies and don’t want to include them into the gift, but you want to eat them yourself instead. For each candy, a number fi is given, which is equal to 0 if you really want to keep i-th candy for yourself, or 1 if you don’t mind including it into your gift. It is possible that two candies of the same type have different values of fi.
You want your gift to be as large as possible, but you don’t want to include too many of the candies you want to eat into the gift. So, you want to calculate the maximum possible number of candies that can be included into a gift, and among all ways to choose maximum number of candies, you want to maximize the number of candies having fi=1 in your gift.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries.
The first line of each query contains one integer n (1≤n≤2⋅105) — the number of candies.
Then n lines follow, each containing two integers ai and fi (1≤ai≤n, 0≤fi≤1), where ai is the type of the i-th candy, and fi denotes whether you want to keep the i-th candy for yourself (0 if you want to keep it, 1 if you don’t mind giving it away).
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print two integers:
the maximum number of candies in a gift you can compose, according to the constraints in the statement;
the maximum number of candies having fi=1 in a gift you can compose that contains the maximum possible number of candies.
Example
inputCopy
3
8
1 0
4 1
2 0
4 1
5 1
6 1
3 0
2 0
4
1 1
1 1
2 1
2 1
9
2 0
2 0
4 1
4 1
4 1
7 0
7 1
7 0
7 1
outputCopy
3 3
3 3
9 5
Note
In the first query, you can include two candies of type 4 and one candy of type 5. All of them have fi=1 and you don’t mind giving them away as part of the gift.
题意:给出n个物品的种类和01属性,要求取出的物品各个种类的个数不同,并且在取出总个数最大的前提下1属性尽可能多
题解:比D题多了一个01属性,所以就不能简单排序直接加了,因为不仅要取出个数最大还要1属性尽可能多。可以先按照每个种类的总个数(也就是0和1的数量)排序求出最大个数,然后按照属性个数(也就是1的数量)进行排序,然后二分1属性个数即可
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
int cnt[200005][2],ac[200005];
struct pot{
int aa;
int bb;
}p[200005];
int ans0,n;
bool cmp(struct pot aa,struct pot bb){
if(aa.aa!=bb.aa)return aa.aa>bb.aa;
return aa.bb>bb.bb;
}
bool cmp2(struct pot aa,struct pot bb){
return aa.bb>bb.bb;
}
bool check(int x){
int ac2=0;
int ac1=0;
set<int>st;
for(int i=1;i<=n;i++){
st.insert(i);
}
set<int>::iterator it;
for(int i=1;i<=n;i++){
it=st.lower_bound(p[i].aa);
if(it==st.begin()&&(*it)>p[i].aa)continue;
if((*it)>p[i].aa)it--;
ac1+=(*it);
ac2+=min((*it),p[i].bb);
st.erase(it);
}
return ac2>=x&&ac1>=ans0;
}
int main()
{
int q;
scanf("%d",&q);
while(q--){
scanf("%d",&n);
for(int i=1;i<=n;i++)cnt[i][0]=cnt[i][1]=0;
for(int i=1;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
cnt[a][b]++;
}
for(int i=1;i<=n;i++){
p[i].aa=cnt[i][0]+cnt[i][1];
p[i].bb=cnt[i][1];
}
sort(p+1,p+1+n,cmp);
ans0=p[1].aa;
int pre=p[1].aa;
for(int i=2;i<=n;i++){
ans0+=max(0,min(p[i].aa,pre-1));
pre=max(0,min(p[i].aa,pre-1));
}
sort(p+1,p+1+n,cmp2);
int L=0;
int R=n;
int ans1;
while(L<=R){
int mid=(L+R)/2;
if(check(mid)){
ans1=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
printf("%d %d\n",ans0,ans1);
}
return 0;
}
H. Subsequences (hard version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between the easy and the hard versions is constraints.
A subsequence is a string that can be derived from another string by deleting some or no symbols without changing the order of the remaining symbols. Characters to be deleted are not required to go successively, there can be any gaps between them. For example, for the string “abaca” the following strings are subsequences: “abaca”, “aba”, “aaa”, “a” and “” (empty string). But the following strings are not subsequences: “aabaca”, “cb” and “bcaa”.
You are given a string s consisting of n lowercase Latin letters.
In one move you can take any subsequence t of the given string and add it to the set S. The set S can’t contain duplicates. This move costs n−|t|, where |t| is the length of the added subsequence (i.e. the price equals to the number of the deleted characters).
Your task is to find out the minimum possible total cost to obtain a set S of size k or report that it is impossible to do so.
Input
The first line of the input contains two integers n and k (1≤n≤100,1≤k≤1012) — the length of the string and the size of the set, correspondingly.
The second line of the input contains a string s consisting of n lowercase Latin letters.
Output
Print one integer — if it is impossible to obtain the set S of size k, print -1. Otherwise, print the minimum possible total cost to do it.
Examples
inputCopy
4 5
asdf
outputCopy
4
inputCopy
5 6
aaaaa
outputCopy
15
inputCopy
5 7
aaaaa
outputCopy
-1
inputCopy
10 100
ajihiushda
outputCopy
233
Note
In the first example we can generate S = { “asdf”, “asd”, “adf”, “asf”, “sdf” }. The cost of the first element in S is 0 and the cost of the others is 1. So the total cost of S is 4.
题意:给出一个字符串,求k个不重复的子序列,要求子序列的总长度最长
题解:dp,dp[i][j]表示到达i处,长度为j的子序列的种类数,容易得出转移方程dp[i][j]=dp[i-1][j]+dp[i-1][j-1],而这样会在当前字符之前出现过的情况下重复计算一些子序列,所以要减去dp[k-1][j-1],其中k就是当前字符在之前出现的最后位置
#include
using namespace std;
#define debug(x) cout<<#x<<" is "<
typedef long long ll;
ll last[27],dp[105][105];
char ch[105];
int main()
{
ll n,k;
scanf("%lld%lld",&n,&k);
scanf("%s",ch+1);
dp[0][0]=1;
for(int i=1;i<=n;i++){
int x=ch[i]-'a';
dp[i][0]=1;
for(int j=0;j<=i;j++){
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
if(last[x])dp[i][j]-=dp[last[x]-1][j-1];
}
last[x]=i;
}
ll ans=0;
for(int i=n;i>=0;i--){
if(k>dp[n][i]){
k-=dp[n][i];
ans+=dp[n][i]*(n-i);
}
else{
ans+=k*(n-i);
printf("%lld\n",ans);
return 0;
}
}
printf("-1\n");
return 0;
}