Codeforces 395 D.Pair of Numbers
2 seconds
256 megabytes
standard input
standard output
Simon has an array a1, a2, ..., an, consisting of n positive integers. Today Simon asked you to find a pair of integers l, r (1 ≤ l ≤ r ≤ n), such that the following conditions hold:
- there is integer j (l ≤ j ≤ r), such that all integers al, al + 1, ..., ar are divisible by aj;
- value r - l takes the maximum value among all pairs for which condition 1 is true;
Help Simon, find the required pair of numbers (l, r). If there are multiple required pairs find all of them.
The first line contains integer n (1 ≤ n ≤ 3·105).
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 106).
Print two integers in the first line — the number of required pairs and the maximum value of r - l. On the following line print all l values from optimal pairs in increasing order.
- 5
4 6 9 3 6
- 1 3
2
- 5
1 3 5 7 9
- 1 4
1
- 5
2 3 5 7 11
- 5 0
1 2 3 4 5
In the first sample the pair of numbers is right, as numbers 6, 9, 3 are divisible by 3.
In the second sample all numbers are divisible by number 1.
In the third sample all numbers are prime, so conditions 1 and 2 are true only for pairs of numbers (1, 1), (2, 2), (3, 3), (4, 4), (5, 5).
题目大意:给出长度为n的序列a[i],要求找到所有满足下列两个条件的子序列a[l],a[l+1],…,a[r]的个数:
1.存在l<=j<=r,使得a[j]是a[l],a[l+1],…,a[r]的最大公因数
2.在所有满足1的子序列中取r-l最长的.
分析:一个序列满足要求当且仅当min = gcd,关键的问题就是如何快速地求出min和gcd,最好是O(1),直接ST表就可以了.接下来二分枚举区间.一般这种求有多少个区间的都是先固定一个左端点然后二分右端点,但是这道题中min和gcd的单调性相同,不能直接这样二分,题目要求最大长度,那么直接二分长度,再枚举起点判断即可.
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int maxn = ;
- int n, f[maxn][], g[maxn][], ans, anss[], tot, cnt, t[], anscnt;
- int gcd(int a, int b)
- {
- if (!b)
- return a;
- return gcd(b, a % b);
- }
- void init()
- {
- for (int j = ; j <= ; j++)
- for (int i = ; i + ( << j) - <= n; i++)
- {
- f[i][j] = min(f[i][j - ], f[i + ( << (j - ))][j - ]);
- g[i][j] = gcd(g[i][j - ], g[i + ( << (j - ))][j - ]);
- }
- }
- int geta(int l, int r)
- {
- int k = (int)((log(r - l + )) / log(2.0));
- return min(f[l][k], f[r - ( << k) + ][k]);
- }
- int getb(int l, int r)
- {
- int k = (int)((log(r - l + )) / log(2.0));
- return gcd(g[l][k], g[r - ( << k) + ][k]);
- }
- bool solve(int x)
- {
- cnt = ;
- int tott = ;
- memset(t, , sizeof(t));
- for (int i = ; i + x <= n; i++)
- if (geta(i, i + x) == getb(i, i + x))
- {
- cnt++;
- t[++tott] = i;
- }
- if (cnt)
- {
- if (x > ans)
- {
- memcpy(anss, t, sizeof(t));
- tot = tott;
- anscnt = cnt;
- }
- return true;
- }
- return false;
- }
- int main()
- {
- scanf("%d", &n);
- for (int i = ; i <= n; i++)
- {
- scanf("%d", &f[i][]);
- g[i][] = f[i][];
- }
- init();
- int l = , r = n;
- while (l <= r)
- {
- int mid = (l + r) >> ;
- if (solve(mid))
- {
- l = mid + ;
- ans = mid;
- }
- else
- r = mid - ;
- }
- if (ans != )
- {
- printf("%d %d\n", anscnt, ans);
- for (int i = ; i <= tot; i++)
- printf("%d ", anss[i]);
- }
- else
- {
- printf("%d %d\n", n, ans);
- for (int i = ; i <= n; i++)
- printf("%d ", i);
- }
- return ;
- }
Codeforces 395 D.Pair of Numbers的更多相关文章
- Codeforces Round #209 (Div. 2) D. Pair of Numbers (模拟)
D. Pair of Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces 385C Bear and Prime Numbers(素数预处理)
Codeforces 385C Bear and Prime Numbers 其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1). 但是,我在统计数组中元素出 ...
- Codeforces 385C Bear and Prime Numbers
题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...
- cf359D Pair of Numbers
Simon has an array a1, a2, ..., an, consisting of n positive integers. Today Simon asked you to find ...
- CodeForces 359D Pair of Numbers (暴力)
题意:给定一个正整数数组,求最长的区间,使得该区间内存在一个元素,它能整除该区间的每个元素. 析:暴力每一个可能的区间,从数组的第一个元素开始考虑,向两边延伸,设延伸到的最左边的点为l, 最右边的点为 ...
- [codeforces] 359D Pair of Numbers
原题 RMQ st表棵题 要想让一个区间里的所有数都可以整除其中一个数,那么他一定是这个区间内的最小值,并且同时是这个区间的gcd.然后这个问题就转化成了RMQ问题. 维护两个st表,分别是最小值和g ...
- Codeforces 359D Pair of Numbers | 二分+ST表+gcd
题面: 给一个序列,求最长的合法区间,合法被定义为这个序列的gcd=区间最小值 输出最长合法区间个数,r-l长度 接下来输出每个合法区间的左端点 题解: 由于区间gcd满足单调性,所以我们可以二分区间 ...
- Educational Codeforces Round 2 A. Extract Numbers 模拟题
A. Extract Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/600/pr ...
- CodeForces - 385C Bear and Prime Numbers (埃氏筛的美妙用法)
Recently, the bear started studying data structures and faced the following problem. You are given a ...
随机推荐
- 75.[LeetCode] Sort Colors
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...
- 一个简单的rest_framework demo
models.py from django.db import models class UserInfo(models.Model): username = models.CharField(max ...
- 后端编程语言PHP
| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.PHP 简介 PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言. PHP 脚本在服务器上执行. 什么是 PHP?(超文本预处理器 ...
- C++Primer第五版——习题答案和解析
感谢原文博主的分享:https://blog.csdn.net/misayaaaaa/article/details/53786215 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西 ...
- C++ Primer Plus学习:第三章
C++入门第三章:处理数据 面向对象编程(OOP)的本质是设计并扩展自己的数据类型. 内置的C++数据类型分为基本类型和复合类型. 基本类型分为整数和浮点数. 复合类型分为数组.字符串.指针和结构. ...
- 转 下一代云计算模式:Docker正掀起个性化商业革命
下一代云计算模式:Docker正掀起个性化商业革命 作者: 吴宁川 来源: ITValue 发布时间: 2015-09-20 10:41 阅读: 14052 次 推荐: 26 原文链接 ...
- 初识ES6 解构
1.数组的解构 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 例子: let [a, b, c] = [1, 2, 3]; console.log(a);//1cons ...
- 0325 实验一操作系统模拟cmd
实验一.命令解释程序的编写 专业:商软(2)班 姓名:韩麒麟 学号:201406114253 一. 实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程 ...
- CDN问题
名称解释:正反向解析 主辅服务器 domain zone 记录:SOA.NS.A.CNAME.PRT.MX DNS配置文件中各字段作用,如TTL DNS端口号? TCP53和UDP53使用场合 Lin ...
- Alpha阶段敏捷冲刺 DAY5
一.举行站立式例会 1.今天我们利用晚上的时间开展了站立会议,总结了一下之前工作的问题,并且制定了明天的计划. 2.站立式会议照片 二.团队报告 1.昨日已完成的工作 (1)改进了程序算法 (2)优化 ...