2016多校联赛1D GCD(HDU5726)
来源:互联网 发布:外国人眼中的中国知乎 编辑:程序博客网 时间:2024/05/06 11:41
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726
GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1151 Accepted Submission(s): 354
Problem Description
Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000) . There are Q(Q≤100,000) queries. For each query l,r you have to calculate gcd(al,,al+1,...,ar) and count the number of pairs(l′,r′)(1≤l<r≤N) 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 numberN , denoting the number of integers.
The second line containsN integers, a1,...,an(0<ai≤1000,000,000) .
The third line contains a numberQ , denoting the number of queries.
For the nextQ lines, i-th line contains two number , stand for the li,ri , stand for the i-th queries.
The first line of each case contains a number
The second line contains
The third line contains a number
For the next
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 forgcd(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) .
For each query, you need to output the two numbers in a line. The first number stands for
Sample Input
151 2 4 6 741 52 43 44 4
Sample Output
Case #1:1 82 42 46 1
Author
HIT
Source
2016 Multi-University Training Contest 1
思路:先预处理一下f数组
f[i][j]=以i为起点的2^j个数 f[1][0]=gcd(a[1]) f[2][1]=fcd(a[2],a[3])...
可以知道 f[i][j]=gcd(f[i][j-1],f[i+(1<<j-1)][j-1]);
那么我们就可以轻松O(1)找到任意区间的gcd
比如找区间L,R 则可以这样算 int k=log2(R-L+1); return gcd(f[L][k],f[R-(1<<k)+1][k]);
用mp[value]记录区间gcd的值为value的个数。
再计算区间gcd值的个数的时候
我们先枚举起点,二分终点(因为一个区间的gcd值是单调不递增的嘛),然后不断更新mp[value]
具体过程还是看代码吧:
#include<map>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int maxn=100005;map<int,LL>mp;LL gcd(LL x,LL y){return x%y==0?y:gcd(y,x%y);}LL n,a[maxn],f[111111][55];void presolve()//预处理f数组,f[i][j]表示gcd(a[i],a[i+1]...a[i+2^j-1])也就是a[i] 为起点2^j个数的gcd { for(int i=n;i>=1;i--) { for(int j=0;i+(1<<j)-1<=n;j++) { if(j==0)f[i][j]=a[i]; else f[i][j]=gcd(f[i][j-1],f[i+(1<<j-1)][j-1]); } }}LL getgcd(int L,int R)//O(1)查询区间gcd; { int k=log2(R-L+1); return gcd(f[L][k],f[R-(1<<k)+1][k]);}int main(){ int T; scanf("%d",&T); for(int t=1;t<=T;t++) { scanf("%lld",&n); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++)scanf("%lld",&a[i]);; int q,l,r; presolve(); for(int i=1;i<=n;i++)//枚举左端点 { int start=i; while(start<=n) { int head=start; int tail=n; int value=getgcd(i,start); int cnt=0; while(head<=tail) { int mid=(head+tail)>>1; int temp=getgcd(i,mid); if(temp==value) { head = mid+1; cnt = mid; } if(temp<value) tail = mid-1; else head = mid+1,cnt=mid; } mp[value]+=cnt-start+1;//每次算完更新数量 start=tail+1; } } printf("Case #%d:\n",t); scanf("%d",&q); while(q--) { scanf("%d%d",&l,&r); int ans=getgcd(l,r); cout<<ans<<" "<<mp[ans]<<endl; } mp.clear(); }}
0 0
- 2016多校联赛1D GCD(HDU5726)
- HDU5726 GCD 二分查找加RMQ 多校联赛第一场
- hdu5726 GCD(乱搞)(2016多校第一场B题)
- hdu5726 GCD 多校1
- (多校第一场1004)HDU5726 GCD(区间GCD查询+)
- 【HDU5726 2016 Multi-University Training Contest 1D】【gcd的下降性质 STL-map】GCD 多少段区间gcd等于给定区间gcd
- hdu5726 GCD(二分+RMQ)
- hdu5726 - GCD (RMQ + 二分)
- hdu5726 GCD (线段树+区间gcd)
- HDU5726 GCD
- hdu5726 GCD
- hdu5726 GCD
- HDU5726 GCD
- HDU5726-GCD
- 2016多校联赛2D Eureka(hdu 5738)
- 2016 多校联赛 第一场 HDU 5726 GCD
- 2016 hdu多校联赛1004 GCD rmq+二分
- hdu5726 多校1 GCD【rmq+二分】
- 四、使用SDk对ZYNQ调试
- python list 对时间排序小结。
- std::distance
- 农夫过河问题学习笔记
- 自定义View之MenuItemView
- 2016多校联赛1D GCD(HDU5726)
- LeetCode专题----动态规划
- NYOJ_228_士兵杀敌(五)
- change project compliance and jre to 1.5
- Eclipse的xml编译插件 安装XMLBuddy
- Tomcat为Cookie设置HttpOnly属性
- linux系统级定时任务 crontab 研究
- 统计同成绩学生人数
- div 加伪类:focus