Codeforces 614
作者:互联网
614 D
题意210 题意115
还要加一句话:输出操作后的序列。
解
思路:
只有两种操作是合法的:
- 将所有水平值最小的技能升高
- 将水平值最高的技能升高到 \(A\)
于是可以枚举一维,二分一维
解法:处理一个初始水平值的前缀和,暴力枚举操作2,二分出操作1升高到的值,在这个二分的check
函数中再写一个二分算出所需的代价看看是否符合条件。\(O(n\log ^2n)\)亲测可过。
至于怎么输出操作后的序列,看代码。
Code
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef long long D;
typedef pair<D,D> P;
template<typename tp>
void read(tp& x){
x=0;
char c=getchar();
bool sgn=0;
while((c<'0'||c>'9')&&c!='-')c=getchar();
if(c=='-')sgn=1,c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
if(sgn)x=-x;
}
template<typename tp>
void write(tp x){
if(x<0)putchar('-'),write(-x);
else{
if(x>=10)write(x/10);
putchar(x%10+'0');
}
}
D n,A,cf,cm,m,sum[maxn],res[maxn];
P a[maxn];
bool check(D x,D rest,D i){
D l=1,r=i-1,mid,I=i;
while(l<=r){
mid=(l+r)>>1;
if(a[mid].first>=x)I=mid,r=mid-1;
else l=mid+1;
}
D II=min(I,i);
return x*(II-1)-sum[II-1]<=rest;
}
signed main(){
D cnt=0,cost=0,ANS=-1,MI=-1,POS=-1;
read(n);read(A);read(cf);read(cm);read(m);
for(D i=1;i<=n;i++){
read(a[i].first);
a[i].second=i;
if(a[i].first==A)cnt++;
}
sort(a+1,a+n+1);
n-=cnt;
for(D i=1;i<=n;i++)sum[i]=sum[i-1]+a[i].first;
for(D i=0;i<=n;i++){
if(i){
cost+=A-a[n-i+1].first;
if(cost>m)break;
}
D l=a[1].first,r=A,mid,ans=l;
while(l<=r){
mid=(l+r)>>1;
if(check(mid,m-cost,n-i+1)){
ans=mid;
l=mid+1;
}
else{
r=mid-1;
}
}
if((cnt+i)*cf+ans*cm>ANS){
ANS=(cnt+i)*cf+ans*cm;
MI=ans;
POS=i;
}
}
write(ANS),putchar('\n');
if(MI!=-1&&POS!=-1){
for(D i=n-POS+1;i<=n;i++)a[i].first=A;
for(D i=1;a[i].first<MI&&i<n-POS+1;i++)a[i].first=MI;
}
n+=cnt;
for(D i=1;i<=n;i++)res[a[i].second]=a[i].first;
for(D i=1;i<=n;i++)write(res[i]),putchar(' ');
return 0;
}
614 E
题意
给一个环形项链,每个珠子是一个字母,现在给出项链长度 \(n\) 和每种字母出现的次数,在某个位置剪开,展开后的字符串是一个回文串,要求构造一个项链,使这种位置的个数最多。
Examples
Input
3
4 2 1
Output
1
abacaba
Input
1
4
Output
4
aaaa
Input
2
1 1
Output
0
ab
解
算法: \(\text{gcd}\)
标签:二分,题意,Codeforces,614,mid,while,maxn,ans 来源: https://www.cnblogs.com/BlogOfchc1234567890/p/10366678.html