数据结构_coprime_sequence(互质序列)
coprime_sequence(互质序列)
问题描述
顾名思义,互质序列是满足序列元素的 gcd 为 1 的序列。比如[1,2,3],
[4,7,8],都是互质序列。 [3,6,9]不是互质序列。现在并不要求你找出一个互质
序列,那样太简单了!真正的问题描述是:给定一个序列,删除其中一个元素使
得剩下元素的 gcd 最大,输出这个 gcd。
★数据输入
输入第一行为一个正整数 n。 第二行为 n 个正整数 ai(1<=ai<=10^9)。
80%的数据 2<=n<=1000.
100%的数据 2<=n<=100000.
★数据输出
输出一个正整数,表示最大的 gcd。
| 输入示例 | 输出示例 |
| 3 1 1 1 |
1 |
| 输入示例 | 输出示例 |
| 5 2 2 2 3 2 |
2 |
| 输入示例 | 输出示例 |
| 4 1 2 4 8 |
2 |
★Hint
最大公因数缩写是 gcd。 gcd(a,b,c)=gcd(a,gcd(b,c)).
解题思路
暴力算法小规模可以,但是复杂度达到O(n^2),大规模数据超时。因此必须采用更好的算法。
期初,我的想法是将从左到右算过的数据存下来,即开一个数组,将第1个数的gcd(本身)存在第1个位置,将第1~2个数的gcd存在第2个位置,1~3个数的gcd存在第3个位置,以此类推。
而其中第1~n个数的gcd可由gcd( 1~(n-1)的gcd , 第n个数 )求得 是递推的过程,复杂度O(n)。
但仅仅这样只比暴力节省一半时间。因此,仿照前面的过程,引入从右到左的gcd计算
开等长数组left[] right[] ,将 从左到右 和 从右到左 的gcd递推计算结果分别存入left[] 与right[]
那么除掉下标为 i 的数,其他数的为gcd( left[i-1] , right[i+1]) 首尾做特殊判断
这样遍历一遍,就能找到gcd_max
code
#include <stdio.h>
#include <stdlib.h> int p[] = {};
int left[] = {};
int right[] = {}; void swap(int &a, int &b)
{
a ^= b;
b ^= a;
a ^= b;
} int Getgcd(int n, int m)
{
if (n < m) swap(n, m);
return n%m == ? m : Getgcd(m, n%m);
} int main()
{
// freopen("test.txt","r",stdin);
int n, i, j;
scanf("%d", &n);
// int *p = (int *)malloc(sizeof(int)*n);
for (i = ; i < n; i++)
scanf("%d", p + i); int gcd = -;
for(i=; i<n; i++) //for(i=0;i<n-1;i++)
{
if(i==)
gcd = p[];
else
gcd = Getgcd(p[i],left[i-]);
left[i] = gcd;
}
for(i=n-; i>=; i--) //for(i=n-1;i>0;i--)
{
if(i==n-)
gcd = p[n-];
else
gcd = Getgcd(p[i],right[i+]);
right[i] = gcd;
} int maxgcd = -;
for(i=; i<n; i++) // except p[i]
{
if(i==)
gcd = right[];
else if(i==n-)
gcd = left[n-];
else
gcd = Getgcd(left[i-],right[i+]);
if(gcd>maxgcd) maxgcd = gcd;
}
printf("%d\n",maxgcd); // free(p);
return ;
}
数据结构_coprime_sequence(互质序列)的更多相关文章
- bzoj 4921: [Lydsy六月月赛]互质序列
4921: [Lydsy六月月赛]互质序列 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 188 Solved: 110[Submit][Status ...
- Codeforces 959 树构造 暴力求最小字典序互质序列
A B C 题目给你一个结论 最少需要min((odd,even)个结点可以把一棵树的全部边连起来 要求你输出两颗树 一棵树结论是正确的 另外一棵结论是正确的 正确结论的树很好造 主要是错误的树 题目 ...
- 【bzoj4921】[Lydsy六月月赛]互质序列 暴力
题目描述 给出一个序列,要求删除一段非空区间,使得剩下的数的个数大于等于2.求所有删除方式剩下的数的最大公约数的和. 输入 第一行包含一个正整数n(3<=n<=100000),表示序列的长 ...
- BZOJ4921「Lydsy1706月赛」互质序列
吐槽一下BZOJ没有C++11 题还是不难的 BZOJ 4921 题意 在长度为$ n$的数列中去掉非空的连续一段并保证剩下数字不少于$ 2$ 求合法的所有方案中剩下数字的最大公约数的总和 $Sol ...
- BZOJ4921 互质序列
即求删掉一个子序列的gcd之和.注意到前后缀gcd的变化次数都是log级的,于是暴力枚举前缀gcd和后缀gcd即可. #include<iostream> #include<cstd ...
- [BZOJ 4921][Lydsy1706月赛]互质序列
传送门 因为区间 gcd 的变换不会超过 log 个,所以我们可以暴力枚举区间起点,复杂度是 n*logn 的 #include <bits/stdc++.h> using namespa ...
- 数据结构 elegant_sequence(优雅的序列)
数据结构 elegant_sequence(优雅的序列) 问题描述 如果一个序列的元素的异或和等于 1,我们称这个序列为优雅的序列.现在给你一个 01 序列,和 m 次询问.对于每次询问,给出 l,r ...
- HDU5668 Circle 非互质中国剩余定理
分析:考虑对给定的出圈序列进行一次模拟,对于出圈的人我们显然可以由位置,编号等关系得到一个同余方程 一圈做下来我们就得到了n个同余方程 对每个方程用扩展欧几里得求解,最后找到最小可行解就是答案. 当然 ...
- hdoj1014 互质
Uniform Generator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
随机推荐
- NOI 模拟赛 #3
打开题一看,咦,两道数数,一道猫式树题 感觉树题不可做呀,暴力走人 数数题数哪个呢?感觉置换比矩阵好一些 于是数了数第一题 100 + 0 + 15 = 115 T1 bishop 给若干个环,这些环 ...
- VMware12版虚拟机怎么安装win7系统(详细教程
转自:http://jingyan.baidu.com/article/cd4c29791fcf1b756e6e6034.html VMware12版虚拟机怎么安装win7系统(详细教程) 现 在很多 ...
- java-05String课堂练习
1.阅读以下代码查看输出结果 public class StringPool { public static void main(String args[]) { String s0="He ...
- Bootstrap确定样式让屏幕缩小后布局不乱
解决方案是如下 结果如下:
- STL理论基础、容器、迭代器、算法
一.STL基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段 ...
- bzoj 4591 [Shoi2015]超能粒子炮·改——组合数前缀和
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4591 先说说自己的想法: 从组合意义的角度考虑,从n个里选<=k个,就添加k个空位置, ...
- walle部署系统的使用
在项目开发的时候要管理各种开发 测试 线上环境的代码 部署 回滚等操作 这里可以使用walle walle官网:http://www.walle-web.io/ 学习安装:https://blog.c ...
- array_diff函数的注意事项
array_diff — 计算数组的差集 说明: array array_diff ( array $array1 , array $array2 [, array $... ] ) 对比返回在 ar ...
- 在U盘分区安装Kali并引导live CD 教程以及常见的注意事项
Kali Linux作为强大的全能渗透系统,把它制成Live CD基本算是必备技能了,但是官方提供的文档虽然简单,但是整个U盘都会被占用,确实是有点可惜,结合网上提供的一些思路加上自己的经验,向大家讲 ...
- 2 ignite关键特性
数据注入和流计算: Ignite流式计算允许以可扩展和容错的方式处理连续不中断的数据流.在一个中等规模的集群中,数据注入Ignite的比例会很高,很容易达到每秒百万级的规模. Ignite可以与主要的 ...