[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. subline应用之常用插件

    汉化插件:ChineseLocalzations IMESupport插件:解决软件输入法跟随问题 SublimeREPL插件:可以用于运行和调试一些需要交互的程序如python SublimeCod ...

  2. Chrome下font-size小于12px的解决办法

    自从Chorme取消了-webkit-text-size-adjust,这个问题又变得令人烦恼起来. 好在我们可以利用-webkit-transform这个私有属性. .box{ -webkit-tr ...

  3. [转]Android 如何监听返回键,弹出一个退出对话框

    本文转自:http://blog.csdn.net/sunnyfans/article/details/8094349 Android 如何监听返回键点击事件,并创建一个退出对话框, 防止自己写的应用 ...

  4. ionic back 返回按钮不正常显示&&二级路由点击返回按钮失效无法返回到上一级页面的问题

    很多时候,app不只有一两级路由,还要三四级路由,但是在ionic中,给出的返回键三级或四级无法使用,所以得自定义方法设置返回. 直接贴代码: <ion-nav-buttons side=&qu ...

  5. IO(下)

    7. 标准输入.输出流 7.1 标准输入流 源数据源是标准输入设备(键盘.鼠标.触摸屏)等输入设备.在java中用http://System.in 得到一个 InputStream 字节输入流. 需求 ...

  6. LN : leetcode 416 Partition Equal Subset Sum

    lc 416 Partition Equal Subset Sum 416 Partition Equal Subset Sum Given a non-empty array containing ...

  7. Spring-aop(一)

    写一个计算类,计算前后需要打印日志. interface ArithmeticCalculator { public int add(int i, int j); public int sub(int ...

  8. 【学习笔记】深入理解js原型和闭包(7)——原型的灵活性

    在Java和C#中,你可以简单的理解class是一个模子,对象就是被这个模子压出来的一批一批月饼(中秋节刚过完).压个啥样,就得是个啥样,不能随便动,动一动就坏了. 而在javascript中,就没有 ...

  9. Eigen3的安装

  10. iOS逆向实战与工具使用(微信添加好友自动确认)

    iOS逆向实战与工具使用(微信添加好友自动确认) 原文链接 源码地址 WeChatPlugin-iOS Mac OS 版微信小助手(远程控制.消息防撤回.自动回复.微信多开) 一.前言 本篇主要实现在 ...