zoukankan      html  css  js  c++  java
  • Codeforces 614

    614 D

    题意210 题意115

    还要加一句话:输出操作后的序列。

    思路:
    只有两种操作是合法的:

    1. 将所有水平值最小的技能升高
    2. 将水平值最高的技能升高到 (A)

    于是可以枚举一维,二分一维

    解法:处理一个初始水平值的前缀和,暴力枚举操作2,二分出操作1升高到的值,在这个二分的check函数中再写一个二分算出所需的代价看看是否符合条件。(O(nlog ^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('
    ');
        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

    算法: ( ext{gcd})

  • 相关阅读:
    [自创]mootools所有复选框只能选择一个的功能
    tomcat设置https访问
    更改tomcat运行时标题
    Java日期操作: 查找星期一和星期天
    mysql 常用数据查询
    git pull代码冲突
    antd model form数据不刷新问题
    前端开发常见面试题
    whistle 使用步骤
    windows 环境 启动报错 '.inconfig' 不是内部或外部命令,也不是可运行的程序
  • 原文地址:https://www.cnblogs.com/BlogOfchc1234567890/p/10366678.html
Copyright © 2011-2022 走看看