UPC-魔法序列(结论+枚举)

简介: UPC-魔法序列(结论+枚举)

魔法序列

时间限制: 1 Sec 内存限制: 128 MB

[提交] [状态]

题目描述

小E为了完成公主的任务,需排布魔法阵,从中获得法力。

简单起见,魔法阵可以看成一个长度为n的序列。序列从左到右都摆放了一张符卡,符卡有一个强度ai。法术的释放要每个元素相互配合,取得共鸣效果。一个由一些符卡组成的咒语的魔力值为这个咒语中所有符卡的强度的最大公因数乘以符卡的个数。

小E会从魔法阵中选择一段连续符卡区间[l,r](包括l,r端点),作为吟唱的咒语。她想知道,咒语最大的魔力值是多少。

输入

第一行一个整数n,表示符卡个数。

第二行n个正整数,第i个数表示符卡的强度ai。

输出

输出一个整数,表示最大的魔力值。

样例输入 Copy

5

30 60 20 20 20

样例输出 Copy

80

提示

样例解释

选择区间[2,5],其中gcd(60,20,20,20)=20,故魔力值为(5-2+1)*20=80。

20200401134307494.png

有一个结论是

区间GCD收敛的很快,gcd的种类最多不超过nlogx(x是数的个数)个

找不到证明了……

然后就可以进行优雅的暴力了~

枚举右端点,再每一个右端点内更新并记录gcd的值:记录每一个gcd出现的最靠左的位置,因为相同的gcd和相同的右端点,左端点越靠左,区间长度越长。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn=1e5+100;
ll n,a[maxn];
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
map<ll,ll>mp1;
map<ll,ll>mp;
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    ll res=0;
    for(int i=1;i<=n;i++){///枚举右端点
        mp=mp1;///用之前的区间更新这次对于右端点来说gcd的值和位置
        mp1.clear();
        res=max(res,a[i]);///区间长度是1
        if(!mp1.count(a[i])) mp1[a[i]]=i;
        for(auto it=mp.begin();it!=mp.end();it++){
            ll tmp=gcd(a[i],it->first);
            res=max(res,tmp*(i-it->second+1));
            if(!mp1.count(tmp)) mp1[tmp]=it->second;///记录这次对于下一个右端点的信息
            else mp1[tmp]=min(mp1[tmp],it->second);
        }
    }
    cout<<res<<endl;
    return 0;
}

类似的题:HDU5869

好短……

目录
相关文章
|
6月前
PTA-求简单交错序列前N项和
求简单交错序列前N项和
59 0
|
6月前
|
Python
PTA-第4章-8 求分数序列前N项和
编写程序计算序列 2/1+3/2+5/3+8/5+... 的前N项和,其中每项分子是前一项分子与分母之和,分母是前一项分子。输入一个正整数N,输出部分和,精确到小数点后两位。给定N=20,输出为32.66。以下是代码实现: ```python n = int(input()) sum = 0 a = 2 b = 1 for i in range(1, n + 1): sum += a / b c = a a = a + b b = c print(f&quot;{sum:.2f}&quot;) ```
125 3
|
6月前
PTA-求交错序列前N项和
求交错序列前N项和
41 2
|
存储 索引
零基础VB教程054期:随机抽取不重复的值
零基础VB教程054期:随机抽取不重复的值
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
(枚举)(模拟)(前缀和)(数组模拟哈希)(可二分)1236. 递增三元组
67 0
|
算法 Go C++
leetcode-2321. 拼接数组的最大分数(差分+枚举)
但其实是在找两个数组之间[Left:Right]区间最大差值,差值我们自然而然的就可以想到差分,但是我们这里求的差分数组并不是两个数组前后元素的差值,而是两个数组同一下标的元素差值,这样我们只要找这段差分区间和的最大值就行了
78 0
leetcode-2321. 拼接数组的最大分数(差分+枚举)
【每日一题Day76】LC2042检查句子中的数字是否递增 | 模拟
• 思路:通过split函数获得以空格为分割符的子字符串,判断当前子字符串首字母是否为数字,若是数字,那么与之前出现的数字进行比较,如果不为递增顺序,返回false
83 0
|
Java
Java经典编程习题100例:第2例:给定一个百分制的分数,输出相应的等级
Java经典编程习题100例:第2例:给定一个百分制的分数,输出相应的等级
175 0
UPC-星区划分(并查集+枚举)
UPC-星区划分(并查集+枚举)
82 0
7-16 求符合给定条件的整数集 (15 分)
7-16 求符合给定条件的整数集 (15 分)
108 0