【gcd+stl】UVa1642 Magical GCD

Description

  一个长度为n的数列,选一个连续子序列,使得子序列的公约数*长度最大,求这个最大值。n<=1e5。

Solution

  连续子序列一般都要用滑动窗口是吧(固定r,快速计算最优l,从r转移到r+1时无需重新计算l信息)

  对于一个r,l递减时gcd也一定递减或不变,所以gcd最多有log(a[i])种不同取值 

  那么对于每一个相同的gcd,显然只需要保存最小的l

  转移也很方便,反正最多log种元素,直接每一个暴力转移,有删除、添加、更新操作,用map来水再好不过了。

  大白例题。

Code

  不太会map...现在才知道first&second...膜了一发别人的代码...

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<map>
 5 #define ll long long
 6 using namespace std;
 7
 8 map<ll,ll>a;
 9 ll n,x,ans;
10
11 ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
12
13 int main(){
14     int T;
15     scanf("%d",&T);
16     while(T--){
17         scanf("%lld",&n);
18         a.clear();
19         ans=0;
20         for(int i=1;i<=n;i++){
21             scanf("%lld",&x);
22             if(!a.count(x)) a[x]=i;
23             for(map<ll,ll>::iterator it=a.begin();it!=a.end();){
24                 ll tmp=gcd(x,it->first);
25                 ans=max(ans,tmp*(i-it->second+1));
26                 if(!a.count(tmp))
27                     a[tmp]=it->second;
28                 else
29                     a[tmp]=min(a[tmp],it->second);
30                 if(tmp<it->first)
31                     a.erase(it++);
32                 else it++;
33             }
34         }
35         printf("%lld\n",ans);
36     }
37     return 0;
38 }
时间: 2024-08-29 17:22:44

【gcd+stl】UVa1642 Magical GCD的相关文章

【BZOJ4052】[Cerc2013]Magical GCD 乱搞

[BZOJ4052][Cerc2013]Magical GCD Description 给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12. 求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大. Sample Input 1 5 30 60 20 20 20 Sample Output 80 题解:先思考暴力的做法.我们从一个数开始往左扫,将所有使得gcd改变的位置都记录下来.由于gcd的每次改变都至少/2,所以这样的位置不超过log个. 那么我们

hdoj 1022 Train Problem I 【简易STL】

题意:不解释(这题是学数据结构必做的) 以前自学数据结构的时候,只是会顺序表来模拟栈.最近简单学习了stack头文件 又来做了一遍(还是以前的味道) 代码: #include <stdio.h> #include <stack> #include <string.h> using std::stack; stack<char > s; char s1[100], s2[100]; int vis[10]; char stac[100]; int main()

【转】【C++ STL】深入解析神秘的 --- 仿函数

原文:http://blog.csdn.net/tianshuai1111/article/details/7687983 一,概述        仿函数(functor),就是使一个类的使用看上去象一个函数.其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了. 有些功能的的代码,会在不同的成员函数中用到,想复用这些代码. 1)公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数

【BZOJ 2820】 YY的GCD

2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 807  Solved: 404 [Submit][Status] Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 kAc这种傻×必然不会了,于是向你来请教-- 多组输入 Input 第一行一个整数T 表述数据组数 接下来T行,每行两个正整数,表示

【bzoj4052】[Cerc2013]Magical GCD 暴力

题目描述 给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12. 求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大. 样例输入 1 5 30 60 20 20 20 样例输出 80 题解 暴力 由于$\gcd$具有结合律,所以如果$\gcd(a,b)$比$a$小,那么至少小了一半. 所以所有以一个数为右端点的区间中,本质不同的$\gcd$个数只有$\log a$个. 于是从左向右枚举右端点,统计出以该点为右端点的所有$\gcd$以及区间长度,统计答

【BZOJ 2820】 YY的GCD (莫比乌斯+分块)

YY的GCD Description 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对 kAc这种傻×必然不会了,于是向你来请教…… 多组输入 Input 第一行一个整数T 表述数据组数 接下来T行,每行两个正整数,表示N, M Output T行,每行一个整数表示第i组数据的结果 Sample Input 210 10100 100 Sample Output 302791 Hint T =

【Luogu P2257】YY 的 GCD

题目 求: \[ \sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) \in \mathbb P] \] 有 \(T\) 组数据, \(T\le 10^4, n, m\le 10^7\) 分析 莫比乌斯反演: \[ \begin{align*} & \sum_{i = 1}^n \sum_{j = 1}^m [\gcd(i, j) \in \mathbb P]\ = & \sum_{p \in \mathbb P, p\le \min(n, m)}\sum_

【BZOJ 2820】YY的GCD

线性筛积性函数$g(x)$,具体看Yveh的题解: http://sr16.com:8081/%e3%80%90bzoj2820%e3%80%91yy%e7%9a%84gcd/ #include<cstdio> #include<cstring> #include<algorithm> #define read(x) x=getint() using namespace std; const int N = 1E7 + 3; int getint() { int k =

【C++/STL】list的实现(采用空间配置器和迭代器)

在list库函数的编译中仍然有很多问题,在源代码的编译中有些内容尚未搞懂,在后期的学习中会进行更加深入的学习,希望大家可以对我的问题提出建议和批评,谢谢大家~ 具体的代码如下: #include <iostream> using namespace std; //采用迭代器和空间配置器所实现的双向链表的基本功能 template<class _Ty,class _A = allocator<_Ty> > //定义模板类 class list //list类 { publ