• 福建工程学院第十四届ACM程序设计大赛


    http://www.fjutacm.com/Contest.jsp?cid=705#P4
    其实想清楚了就很简单,之前想了很多种方法,以为是二分什么的,看起来就像是一个单峰函数。但是发现直接暴力一波就行了。
    不知道有没有人会来搜到我的题解?ID是Yinku2017。

    题意:求(x)使得(sumlimits_{i=1}^{n}[a_i/x]+a_i\%x)

    首先把取余运算换成减法。提公因式。
    (sumlimits_{i=1}^{n}[a_i/x]+a_i\%x=sumlimits_{i=1}^{n}{[a_i/x]+a_i-x[a_i/x]}=sumlimits_{i=1}^{n}a_i+sumlimits_{i=1}^{n}{(1-x)[a_i/x]})
    发现什么?枚举x,根据某个n/1+n/2+n/3+...+n/n=nlogn的式子,前缀和计算出后半部分的值。恰好a_i最大就是1e6,可以这么搞,估计这道题已经设计好a_i就是1e6的。

    小心溢出就可以了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n;
    int a[1000005]={};
    int pa[2000005]={};
    
    int maxa=0;
    ll sum=0;
    ll minans=0;
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
    #endif // Yinku
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int t;
            scanf("%d",&t);
            if(t>maxa)
                maxa=t;
            sum+=t;
            a[t]++;
        }
    
        for(int i=1;i<=maxa*2;i++){
            pa[i]=pa[i-1]+a[i];
        }
    
        for(int d=2;d<=maxa;d++){
            ll tminans=0;
            int c=(maxa+d-1)/d;
            for(int j=1;j<=c;j++){
                if(j*d>maxa)
                    break;
                tminans+=1ll*(pa[(j+1)*d-1]-pa[j*d-1])*j;
            }
    
            tminans*=(1ll-d);
            if(minans>tminans)
                minans=tminans;
        }
    
        printf("%lld
    ",sum+minans);
    }
    
  • 相关阅读:
    docker
    redis 3.2.6 on ubuntu 14.04
    go异常处理
    go语言的命令行库
    iptables
    nsq
    etcd-v2第一集
    rabbitmq, windows/linux, c/c++/node.js/golang/dotnet
    zeromq:c,c++,golang及nodejs使用
    golang下的grpc
  • 原文地址:https://www.cnblogs.com/Yinku/p/10862779.html
Copyright © 2020-2023  润新知