[BZOJ4052][Cerc2013]Magical GCD

试题描述

给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12。 
求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大。

输入

本题为多组数据。

第一行一个整数 T,表示数据组数。

每组数据第一行为一个整数 n,表示序列长度;第二行为 n 个整数表示序列。

输出

对于每组数据,输出 max{ gcd * length }

输入示例


输出示例


数据规模及约定

见“试题描述

题解

可以发现,随着子序列的增长,gcd 要么不变,若变化则变化后的 gcd 不会超过原来的 1/2,所以 gcd 的变化次数不会超过 log21012 = 12 · log210 次。

有了上面的结论,我们就可以枚举左端点,然后向右二分 gcd 即将变化的位置(维护区间 gcd 可以用 ST 表),在每个这样的位置更新答案,然后移动子序列右端点,重复这个过程。设数字大小为 A,那么更新答案次数为 log2A;每次二分需要 log2n;哦对了虽然 RMQ 询问复杂度 O(1),但是每次需要取 gcd,最坏情况 log2A;别忘了我们还枚举了左端点有一个 n,所以最终复杂度不会超过 O(n · log22A · log2n)。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
#define LL long long const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
LL read() {
LL x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 100010
#define maxlog 17
int n;
LL A[maxn]; LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } LL Gcd[maxlog][maxn];
int Log[maxn];
void rmq_init() {
Log[1] = 0;
for(int i = 2; i <= n; i++) Log[i] = Log[i>>1] + 1;
for(int i = 1; i <= n; i++) Gcd[0][i] = A[i];
for(int j = 1; (1 << j) <= n; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++)
Gcd[j][i] = gcd(Gcd[j-1][i], Gcd[j-1][i+(1<<j-1)]);
return ;
}
LL query(int l, int r) {
int len = r - l + 1, t = Log[len];
return gcd(Gcd[t][l], Gcd[t][r-(1<<t)+1]);
} int main() {
int T = read();
while(T--) {
n = read();
for(int i = 1; i <= n; i++) A[i] = read(); rmq_init();
LL ans = 0;
for(int L = 1; L <= n; L++) {
int R = L; LL tmp = query(L, R);
while(R < n) {
int l = R, r = n + 1;
while(r - l > 1) {
int mid = l + r >> 1;
if(query(L, mid) == tmp) l = mid; else r = mid;
}
R = l;
ans = max(ans, tmp * (R - L + 1));
R++; tmp = query(L, R);
}
if(R <= n) ans = max(ans, tmp * (R - L + 1)); // mark!!
} printf("%lld\n", ans);
} return 0;
}

大视野数据好强!我就因为少加 "mark!!" 那一行导致 WA 了一上午。。。

[BZOJ4052][Cerc2013]Magical GCD的更多相关文章

  1. 【数论】【暴力】bzoj4052 [Cerc2013]Magical GCD

    考虑向一个集合里添加一个数,它们的gcd要么不变,要么变成原gcd的一个约数.因此不同的gcd只有log个. 所以对于每个位置,维护一个表,存储从这个位置向前所有的不同的gcd及其初始位置,然后暴力更 ...

  2. 【BZOJ4052】[Cerc2013]Magical GCD 乱搞

    [BZOJ4052][Cerc2013]Magical GCD Description 给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12.  求一个连续子序列,使得在所有的连续 ...

  3. 4052: [Cerc2013]Magical GCD

    4052: [Cerc2013]Magical GCD Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 148  Solved: 70[Submit][ ...

  4. 【bzoj4052】[Cerc2013]Magical GCD 暴力

    题目描述 给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12.  求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大. 样例输入 1 5 30 60 2 ...

  5. BZOJ 4052: [Cerc2013]Magical GCD

    以一个数字开头的子序列的gcd种类不会超过logn种,因此去找相同gcd最长的位置,更新一下答案,复杂度O(nlogn^2) #include<cstdio> #include<al ...

  6. [Cerc2013]Magical GCD

    https://vjudge.net/problem/UVA-1642 题意:在一个序列中,找出一段连续的序列,使得长度*gcd最大 固定右端点,当左端点从左向右移动时,gcd不变或变大 gcd相同时 ...

  7. BZOJ.4052.[Cerc2013]Magical GCD(思路)

    BZOJ \(Description\) 给定\(n\)个数的序列\(a_i\).求所有连续子序列中,序列长度 × 该序列中所有数的gcd 的最大值. \(n\leq10^5,\ a_i\leq10^ ...

  8. 【BZOJ】【4052】【CERC2013】Magical GCD

    DP/GCD 然而蒟蒻并不会做…… Orz @lct1999神犇 首先我们肯定是要枚举下端点的……嗯就枚举右端点吧…… 那么对于不同的GCD,对应的左端点最多有log(a[i])个:因为每次gcd缩小 ...

  9. Magical GCD UVA 1642 利用约数个数少来优化 给定n个数,求使连续的一段序列的所有数的最大公约数*数的数量的值最大。输出这个最大值。

    /** 题目:Magical GCD UVA 1642 链接:https://vjudge.net/problem/UVA-1642 题意:给定n个数,求使连续的一段序列的所有数的最大公约数*数的数量 ...

随机推荐

  1. 【译】建立属于你的个人高效系统——效率专家 Mike Vardy 教你如何设置一个简单的个人高效系统

    原文:http://mux.baidu.com/?p=5300 百度MUX 已经有太多的高效系统供人使用,而对于那些刚刚开始,想寻求更好方法完成他们任务,项目,目标的人来说,要做一个高效系统却是相当艰 ...

  2. Win10新机的安装与配置

    一.快捷键 打开Chrome上次关闭的所有标签页:Ctrl-Shift-T 二.问题解决 1. 右键取得管理员权限 https://www.tenforums.com/tutorials/3841-a ...

  3. P1739 表达式括号匹配

    题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”:否则返 ...

  4. Excel数据直接到DataTable--->DB

    1) Excel数据直接导入到临时生成的DataTable using (OleDbConnection selectConnection = new OleDbConnection("Pr ...

  5. 自動獲取外網IP并發郵件

    問題: 公司有一Web系統需開放給香港Office公司查詢資料,但最近動態域名需實名認證, 因系統較小型,非公開大範圍使用,所以再認證一域名也沒多大必要, 所以想定時生成一封能查詢外網IP的郵件發送給 ...

  6. WPF学习12:基于MVVM Light 制作图形编辑工具(3)

    本文是WPF学习11:基于MVVM Light 制作图形编辑工具(2)的后续 这一次的目标是完成 两个任务. 本节完成后的效果: 本文分为三个部分: 1.对之前代码不合理的地方重新设计. 2.图形可选 ...

  7. 前端之CSS创建的样式

    CSS即层叠样式表,在创建时有以下几种样式: 1.内联样式(行内样式.行间样式): <标记 style=“属性:属性值:”></标记> 2.内部样式(嵌入式样式): <s ...

  8. SQL Server之增删改操作

    -------添加约束.增删改 use StudentDB2 go --------创建学生表--------- create table StudentInfo( --studentId int p ...

  9. Docker Hello World容器运行报错的解决办法

    费了好大力气从Docker官网下载了Docker Community Editor的安装镜像,Docker.dmg, 总共将近500MB,双击进行安装: 命令行里使用docker version查看版 ...

  10. mybatis中app的查询语句

    SELECT * FROM ( SELECT (@rownum := @rownum + ) AS rownum,c.* FROM (SELECT @rownum := ) r, ( select * ...