Codeforces 731F By Assassin

题目大意,可以从n个带有一定power的原件中选择任意个构成一个两层的树形结构,要求第一层只有一个做根且该点的power不能改变,第二层中的原件必须可以整除根原件,如果不能整除,可以减少一定power使之满足条件。

思路:讲真很简单,就是暴力,关键就是暴力的思路!下面进行分析

1.如果有1的话那么一定就是选择所有的,1为根其他在第二层。不解释了。。。

2.如果不是1,那么我们用一个数组a[]来记录,小于或等于当前power值有多少个,例如n=3  ,1 1 2,那么a[1]=2,a[2]=3.用桶装法即可。这样就能保证,当你用i做根的时候,直接向后索搜就行,因为比i小的不可能在第二层。当检测到a[i]!=a[i-1]时,说明有新数据,这时,从j=i开始,步幅为i向后为i向后遍历!看[j,j+i-1]中间有多少个数,这些数都是一定需要改成j的!

比如  4 5 6 7,9,10,当4为根的时候5,6,7需要变成4,9,10,需要变成8!

注意一个点!j+i可能大于了最大长度(实际找到一组数据中的最大值就可以了,不需要遍历200000),所以加一个判定
tempmax+=a[min(maxpos,j+i-1)]-a[j-1]

之后每次更新即可

上代码

#include<bits/stdc++.h>
#define input freopen("input.txt","r",stdin)
using namespace std;
long long a[200002];
int main()
{
    long long n,k,maxpos,i,j;
    long long sum,flag=0;
    while(scanf("%I64d",&n)!=EOF){
        sum=flag=maxpos=0;
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++){
            scanf("%I64d",&k);
            a[k]++;
            sum+=k;
            if(k==1)flag=1;
            maxpos=max(maxpos,k);
        }
        if(flag){                  //存在1的情况 
            cout<<sum<<endl;
            continue;
        }
        for(i=2;i<=maxpos;i++)
            a[i]+=a[i-1];
        long long ans=0;
        for(i=2;i<=maxpos;i++){    //不存在1,i从2开始即可 
            if(a[i]!=a[i-1]){
                long long tempmax=0;
                for(j=i;j<=maxpos;j+=i)
                    tempmax+=j*(a[min(maxpos,j+i-1)]-a[j-1]);  //注意边界!!! 
                ans=max(ans,tempmax);
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
} 

真是暴力姿势多啊!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值