【JZOJ4922】【NOIP2017提高组模拟12.17】环

介绍了一个算法问题,关于如何将一个带有数值的环形结构通过特定的切割方式达到最大优美程度,即找到最佳的切割数量及位置使得每段数字和的最大公约数最大。讨论了算法的实现思路和代码细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

小A有一个环,环上有n个正整数。他有特殊的能力,能将环切成k段,每段包含一个或者多个数字。对于一个切分方案,小A将以如下方式计算优美程度:
首先对于每一段,求出他们的数字和。然后对于每段的和,求出他们的最大公约数,即为优美程度。
他想通过合理地使用他的特殊能力,使得切分方案的优美程度最大。

数据范围

对于100%的数据,n<=2000,1<=ai<=50000000(5e7)

=w=

sum=ai
那么答案一定是sum的约数。
证明:
如果存在一个答案ans不是sum的约数,那么切分出来的每一段之和都会是ans的倍数;
每一段的和(也就是sum)就会是ans的倍数。
矛盾。

如果切分i段的答案为ans[i],那么对于所有j>i,切分j段的答案至少为ans[i]
证明:
通过子段合并,显然可得。


于是我们得出思路:
枚举sum的一个约数i,容易用哈希表加上O(2n)的时间得出最小的j使得ans[j]=i

代码

// DO NOT FORGET TO OPEN LL
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="aP1.in";
const char* fout="aP1.out";
const ll inf=0x7fffffff;
const ll maxn=4007,maxp=100000,maxh=99997;
ll n,m,i,j,k;
ll a[maxn],w[maxn],ans[maxn],pre[maxn],sum[maxn];
ll id[maxn];
ll h[maxh],cnt[maxh];
ll getsum(ll l,ll r){
    return pre[r]-pre[l-1];
}
ll hash(ll v){
    ll k=v%maxh;
    while (h[k] && h[k]!=v) k=(k+1)%maxh;
    return k;
}
void add(ll x){
    ll i=hash(sum[x]+1);
    id[x]=i;
    if (h[i]==0){
        h[i]=sum[x]+1;
        cnt[i]=1;
    }else cnt[i]++;
}
void del(ll x){
    ll i=id[x];
    cnt[i]--;
    if (!cnt[i]) h[i]=0;
}
ll find(ll x){
    ll i=id[x];
    if (h[i]) return cnt[i];
    else return 0;
}
void solve(ll v){
    ll i,j,k,cnt=0,tmp=0;
    sum[0]=0;
    for (i=1;i<=n;i++) sum[i]=(sum[i-1]+a[i])%v;
    for (i=1;i<=n/2;i++) add(i);
    for (i=n/2+1;i<=n;i++){
        //tong[sum[i-n/2]]--;
        del(i-n/2);
        add(i);
        if (sum[i]==sum[i-n/2]){
            tmp=max(find(i-n/2),tmp);
        }
    }
    w[tmp]=max(w[tmp],v);
    for (i=n/2+1;i<=n;i++) del(i);
}
int main(){
    scanf("%lld",&n);
    for (i=1;i<=n;i++) scanf("%lld",&a[i]),m+=a[i];
    for (i=n+1,j=n*2;i<=j;i++) a[i]=a[i-n];
    for (i=1;i<=n;i++) pre[i]=a[i]+pre[i-1];
    n=n*2;
    for (i=1,j=(ll)sqrt(m);i<=j;i++){
        if (m%i==0) solve(i),solve(m/i);
    }
    k=1;
    for (i=n/2;i>0;i--){
        k=max(k,w[i]);
        ans[i]=k;
    }
    for (i=1;i<=n/2;i++) printf("%lld\n",ans[i]);
    return 0;
}

=o=

其实优化容易想到。
我没深入思考= =

转载于:https://www.cnblogs.com/hiweibolu/p/6714814.html

1. 用户与身体信息管理模块 用户信息管理: 注册登录:支持手机号 / 邮箱注册,密码加密存储,提供第三方快捷登录(模拟) 个人资料:记录基本信息(姓名、年龄、性别、身高、体重、职业) 健康目标:用户设置目标(如 “减重 5kg”“增肌”“维持健康”)及期望周期 身体状态跟踪: 体重记录:定期录入体重数据,生成体重变化曲线(折线图) 身体指标:记录 BMI(自动计算)、体脂率(可选)、基础代谢率(根据身高体重估算) 健康状况:用户可填写特殊情况(如糖尿病、过敏食物、素食偏好),系统据此调整推荐 2. 膳食记录与食物数据库模块 食物数据库: 基础信息:包含常见食物(如米饭、鸡蛋、牛肉)的名称、类别(主食 / 肉类 / 蔬菜等)、每份重量 营养成分:记录每 100g 食物的热量(kcal)、蛋白质、脂肪、碳水化合物、维生素、矿物质含量 数据库维护:管理员可添加新食物、更新营养数据,支持按名称 / 类别检索 膳食记录功能: 快速记录:用户选择食物、输入食用量(克 / 份),系统自动计算摄入的营养成分 餐次分类:按早餐 / 午餐 / 晚餐 / 加餐分类记录,支持上传餐食照片(可选) 批量操作:提供常见套餐模板(如 “三明治 + 牛奶”),一键添加到记录 历史记录:按日期查看过往膳食记录,支持编辑 / 删除错误记录 3. 营养分析模块 每日营养摄入分析: 核心指标计算:统计当日摄入的总热量、蛋白质 / 脂肪 / 碳水化合物占比(按每日推荐量对比) 微量营养素分析:检查维生素(如维生素 C、钙、铁)的摄入是否达标 平衡评估:生成 “营养平衡度” 评分(0-100 分),指出摄入过剩或不足的营养素 趋势分析: 周 / 月营养趋势:用折线图展示近 7 天 / 30 天的热量、三大营养素摄入变化 对比分析:将实际摄入与推荐量对比(如 “蛋白质摄入仅达到推荐量的 70%”) 目标达成率:针对健
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值