博客
关于我
魔法序列-upc
阅读量:282 次
发布时间:2019-03-01

本文共 3052 字,大约阅读时间需要 10 分钟。

为了解决这个问题,我们需要找到一个连续区间,使得这个区间内所有符卡的最大公约数乘以区间的长度最大的那个值。这个问题可以通过分治法来高效解决。

方法思路

  • 分治法分割问题:将数组分成左右两部分,分别计算左右子区间的最大贡献值。
  • 预处理前缀和后缀GCD数组:前缀GCD数组记录从数组起点到当前位置的所有数的最大公约数,后缀GCD数组记录从当前位置到数组终点的最大公约数。
  • 合并左右子区间:在合并左右子区间时,需要考虑中间区间的GCD是否可以与左边或右边的某些数结合,形成更大的贡献值。
  • 解决代码

    #include 
    #include
    #include
    using namespace std;struct Result { int max_power; int current_gcd; int start_pos;};int gcd(int a, int b) { while (b != 0) { int temp = a % b; a = b; b = temp; } return a;}vector
    compute_prefix_gcd(const vector
    & a) { vector
    prefix(a.size(), 0); prefix[0] = a[0]; for (int i = 1; i < a.size(); ++i) { prefix[i] = gcd(prefix[i-1], a[i]); } return prefix;}vector
    compute_suffix_gcd(const vector
    & a) { vector
    suffix(a.size(), 0); suffix[a.size()-1] = a[a.size()-1]; for (int i = a.size()-2; i >= 0; --i) { suffix[i] = gcd(suffix[i+1], a[i]); } return suffix;}Result max_power(int left, int right, const vector
    & a, const vector
    & prefix, const vector
    & suffix) { if (left > right) return {0, 0, left}; if (left == right) return {a[left], a[left], left}; int mid = (left + right) / 2; Result left_res = max_power(left, mid, a, prefix, suffix); Result right_res = max_power(mid+1, right, a, prefix, suffix); int combined_gcd = gcd(left_res.current_gcd, right_res.current_gcd); int combined_length = right - left + 1; int combined_power = combined_gcd * combined_length; if (combined_power > left_res.max_power && combined_power > right_res.max_power) { return {combined_power, combined_gcd, left}; } int mid_gcd = gcd(a[mid], a[mid+1]); if (mid_gcd != left_res.current_gcd && mid_gcd != right_res.current_gcd) { mid_gcd = gcd(mid_gcd, a[mid]); mid_gcd = gcd(mid_gcd, a[mid+1]); } int mid_length = mid - left + 1; int mid_power = mid_gcd * mid_length; if (mid_power > left_res.max_power) { left_res.max_power = mid_power; } mid_length = right - mid; mid_gcd = gcd(a[mid+1], a[mid]); mid_power = mid_gcd * mid_length; if (mid_power > right_res.max_power) { right_res.max_power = mid_power; } if (left_res.max_power > right_res.max_power) { return left_res; } else { return right_res; }}int main() { int n; read(n); vector
    a(n); for (int i = 0; i < n; ++i) { a[i] = read(); } vector
    prefix = compute_prefix_gcd(a); vector
    suffix = compute_suffix_gcd(a); Result res = max_power(0, n-1, a, prefix, suffix); cout << res.max_power << endl; return 0;}

    代码解释

  • 结构体Result:用于存储当前区间的最大贡献值、当前GCD以及区间起始位置。
  • GCD函数:计算两个数的最大公约数。
  • 前缀和后缀GCD数组:预处理数组的前缀和后缀GCD数组,用于快速查询区间内的GCD。
  • 分治函数max_power:递归地计算当前区间的最大贡献值,处理左右子区间并合并结果。
  • 合并处理:在合并左右子区间时,考虑中间区间的GCD是否可以与左边或右边的某些数结合,形成更大的贡献值。
  • 通过这种方法,我们可以高效地找到最大的魔力值。

    转载地址:http://kloo.baihongyu.com/

    你可能感兴趣的文章
    NLP_什么是统计语言模型_条件概率的链式法则_n元统计语言模型_马尔科夫链_数据稀疏(出现了词库中没有的词)_统计语言模型的平滑策略---人工智能工作笔记0035
    查看>>
    NLP学习笔记:使用 Python 进行NLTK
    查看>>
    NLP的神经网络训练的新模式
    查看>>
    NLP采用Bert进行简单文本情感分类
    查看>>
    NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估
    查看>>
    NLP:使用 SciKit Learn 的文本矢量化方法
    查看>>
    Nmap扫描教程之Nmap基础知识
    查看>>
    Nmap端口扫描工具Windows安装和命令大全(非常详细)零基础入门到精通,收藏这篇就够了
    查看>>
    NMAP网络扫描工具的安装与使用
    查看>>
    NMF(非负矩阵分解)
    查看>>
    nmon_x86_64_centos7工具如何使用
    查看>>
    NN&DL4.1 Deep L-layer neural network简介
    查看>>
    NN&DL4.3 Getting your matrix dimensions right
    查看>>
    NN&DL4.8 What does this have to do with the brain?
    查看>>
    nnU-Net 终极指南
    查看>>
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    查看>>
    NO 157 去掉禅道访问地址中的zentao
    查看>>
    no available service ‘default‘ found, please make sure registry config corre seata
    查看>>
    no connection could be made because the target machine actively refused it.问题解决
    查看>>
    No Datastore Session bound to thread, and configuration does not allow creation of non-transactional
    查看>>