【HDU5726 2016 Multi-University Training Contest 1D】【gcd的下降性质 STL-map】GCD 多少段区间gcd等于给定区间gcd

本文主要是介绍【HDU5726 2016 Multi-University Training Contest 1D】【gcd的下降性质 STL-map】GCD 多少段区间gcd等于给定区间gcd,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GCD

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2189    Accepted Submission(s): 731


Problem Description
Give you a sequence of N(N100,000) integers : a1,...,an(0<ai1000,000,000) . There are Q(Q100,000) queries. For each query l,r you have to calculate gcd(al,,al+1,...,ar) and count the number of pairs (l,r)(1l<rN) such that gcd(al,al+1,...,ar) equal gcd(al,al+1,...,ar) .

Input
The first line of input contains a number T , which stands for the number of test cases you need to solve.

The first line of each case contains a number N , denoting the number of integers.

The second line contains N integers, a1,...,an(0<ai1000,000,000) .

The third line contains a number Q , denoting the number of queries.

For the next Q lines, i-th line contains two number , stand for the li,ri , stand for the i-th queries.

Output
For each case, you need to output “Case #:t” at the beginning.(with quotes, t means the number of the test case, begin from 1).

For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs (l,r) such that gcd(al,al+1,...,ar) equal gcd(al,al+1,...,ar) .

Sample Input
  
1 5 1 2 4 6 7 4 1 5 2 4 3 4 4 4

Sample Output
  
Case #1: 1 8 2 4 2 4 6 1

Author
HIT

Source
2016 Multi-University Training Contest 1

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
int n, v[N];
vector< pair<int,int> >lft[N];
int gcd(int x, int y)
{return y == 0 ? x : gcd(y, x%y);
}
map<int, LL>mop;
void STinit()
{lft[n + 1].clear(); for (int i = n; i >= 1; i--){lft[i].clear();int p = i; int g = v[i];for (auto& it : lft[i + 1]){int newg = gcd(g, it.second);if (newg != g)lft[i].push_back(MP(p, g));p = it.first;g = newg;}lft[i].push_back(MP(p, g));p = i - 1;for (auto& it : lft[i]){mop[it.second] += it.first - p;p = it.first;}}
}
int getgcd(int l, int r)
{for (auto& it : lft[l]){if (r <= it.first)return it.second;}
}
int main()
{scanf("%d", &casenum);for (casei = 1; casei <= casenum; ++casei){mop.clear();scanf("%d", &n); for (int i = 1; i <= n; ++i)scanf("%d", &v[i]);STinit();int q; scanf("%d", &q);printf("Case #%d:\n", casei);while (q--){int l, r; scanf("%d%d", &l, &r);int g = getgcd(l, r);printf("%d %lld\n", g, mop[g]);}}return 0;
}
/*
【trick&&吐槽】
比赛的时候把最后一个区间段忘记加进去了,导致吃了一发WA,悲剧!【题意】
有n(1e5)个数,
每次给你一个区间段,
问你有多少个区间段内的gcd与该区间段的gcd是相同的,输出这样的区间个数。【类型】
gcd的下降性质【分析】
我们以一个点为区间的左界,然后逐渐扩展右界,gcd一旦变化了,至少也会变为原来的一半。
所以gcd的变化区间段数最多为logn段。
于是我们可以以区间的右侧开始,向右方向扩展gcd,然后存到map中。
这个预处理的复杂度是O(nlogn)
接下来对于单组数据的查询和询问,复杂度也是O(nlogn),这道题就做完了。【时间复杂度&&优化】
O(nlogn)*/


这篇关于【HDU5726 2016 Multi-University Training Contest 1D】【gcd的下降性质 STL-map】GCD 多少段区间gcd等于给定区间gcd的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610389

相关文章

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

2014 Multi-University Training Contest 8小记

1002 计算几何 最大的速度才可能拥有无限的面积。 最大的速度的点 求凸包, 凸包上的点( 注意不是端点 ) 才拥有无限的面积 注意 :  凸包上如果有重点则不满足。 另外最大的速度为0也不行的。 int cmp(double x){if(fabs(x) < 1e-8) return 0 ;if(x > 0) return 1 ;return -1 ;}struct poin

2014 Multi-University Training Contest 7小记

1003   数学 , 先暴力再解方程。 在b进制下是个2 , 3 位数的 大概是10000进制以上 。这部分解方程 2-10000 直接暴力 typedef long long LL ;LL n ;int ok(int b){LL m = n ;int c ;while(m){c = m % b ;if(c == 3 || c == 4 || c == 5 ||

2014 Multi-University Training Contest 6小记

1003  贪心 对于111...10....000 这样的序列,  a 为1的个数,b为0的个数,易得当 x= a / (a + b) 时 f最小。 讲串分成若干段  1..10..0   ,  1..10..0 ,  要满足x非递减 。  对于 xi > xi+1  这样的合并 即可。 const int maxn = 100008 ;struct Node{int

hdu4267区间统计

题意:给一些数,有两种操作,一种是在[a,b] 区间内,对(i - a)% k == 0 的加value,另一种操作是询问某个位置的值。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import

hdu4417区间统计

给你一个数列{An},然后有m次查询,每次查询一段区间 [l,r] <= h 的值的个数。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamRead

hdu3333区间统计

题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验

C++ STL 适配器

系列文章目录 模板特例化,偏特化,左右值引用 https://blog.csdn.net/surfaceyan/article/details/126794013 C++ STL 关联容器 https://blog.csdn.net/surfaceyan/article/details/127414434 C++ STL 序列式容器(二) https://blog.csdn.net/surfac