hdu5726 GCD(乱搞)(2016多校第一场B题)
来源:互联网 发布:php中文网学费 编辑:程序博客网 时间:2024/04/29 03:31
题目链接:点这里!!!
题意:给你n个数a1,a2,a3...an(n<=1e5,1<=ai<=1e9),给你q个询问[l,r]。
问你gcd(al,al+1,al+2...ar)为多少?再问你有多少个pair(l',r')(1<=l'<=r'<=n)使得gcd(al',al'+1...ar')与gcd(al,al+1,al+2...ar)为多少?
题解:
1、询问gcd(al,al+1,al+2...ar)我们可以利用类似于rmq的思想在O(nlog(n))预处理,O(1)询问得到,我们设询问得到的答案为f。
2、对于求有多少个pair(l',r')对应的答案为f,我们可以预处理出来。
3、我们枚举左端点,然后一直往n方向一直gcd下来,我们发现gcd一直是减小的,而且我们发现他最多下降30次(2^30为1e9左右)。
我们就可以通过二分去求,再统计起来就ok啦!!!
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<bitset>#include<set>#include<queue>#include<stack>#include<map>#include<cstdlib>#include<cmath>#define LL long long#define pb push_back#define pa pair<int,int>#define clr(a,b) memset(a,b,sizeof(a))#define lson lr<<1,l,mid#define rson lr<<1|1,mid+1,r#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)#define key_value ch[ch[root][1]][0]#pragma comment(linker, "/STACK:102400000000,102400000000")const LL MOD = 1000000007;const int N = 1e5+15;const int maxn = 1e5+15;const int letter = 130;const LL INF = 1e18;const double pi=acos(-1.0);const double eps=1e-10;using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}int q,n,a[N],dp[N][20];int mm[N];map<int,LL>mp;int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b);}void initrmq(int n,int a[]){ mm[0]=-1; for(int i=1;i<=n;i++){ mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1]; dp[i][0]=a[i]; } for(int j=1;j<=mm[n];j++) for(int i=1;i+(1<<j)-1<=n;i++){ dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); }}int rmq(int x,int y){ int k=mm[y-x+1]; return gcd(dp[x][k],dp[y-(1<<k)+1][k]);}int main(){ int T,cas=0; scanf("%d",&T); while(T--){ mp.clear(); clr(dp,0); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); initrmq(n,a); for(int i=1;i<=n;i++){ int l=i,r=n,mid,vs,ans,pp; while(1){ ans=l; pp=l; vs=rmq(i,l); /// printf("i = %d vs = %d\n",i,vs); while(l<=r){ mid=(l+r)>>1; if(rmq(i,mid)<vs) r=mid-1; else ans=mid,l=mid+1; } mp[vs]+=1LL*(ans-pp+1); /// printf("ps = %d %d %d\n",ans,rmq(i,ans),mp[rmq(i,ans)]); l=ans+1,r=n; if(l>r) break; } } scanf("%d",&q); printf("Case #%d:\n",++cas); int l,r; while(q--){ scanf("%d%d",&l,&r); int vs=rmq(l,r); printf("%d %I64d\n",vs,mp[vs]); } } return 0;}
0 0
- hdu5726 GCD(乱搞)(2016多校第一场B题)
- (多校第一场1004)HDU5726 GCD(区间GCD查询+)
- HDU5726 GCD 二分查找加RMQ 多校联赛第一场
- 2016多校联赛1D GCD(HDU5726)
- 2016多校第一场1004 hdu 5726 GCD
- 2016 多校联赛 第一场 HDU 5726 GCD
- HDU5726 GCD
- hdu5726 GCD
- hdu5726 GCD
- HDU5726 GCD
- HDU5726-GCD
- 17暑假多校第一场B
- 2016多校联合训练赛 第一场1004 GCD hdu 5726
- hdu 5726 GCD 2016多校赛第一场
- 2016多校第一场
- HDU5726 GCD【RMQ+二分】
- hdu5726 GCD 多校1
- Hdu5726:GCD—题解
- c_str()的介绍与用法
- EM算法与高斯混合聚类
- 《leetcode》:Find Median from Data Stream
- 量子力学初识
- c++——将数组中重复的数剔除
- hdu5726 GCD(乱搞)(2016多校第一场B题)
- 为何10M多的视频传不上sae云应用的目录,是不是要放在sae云存储里面??
- markdown编辑器练习
- C++ string 详解
- 使用adb shell am start -w packagename/activity查看app耗时碰到的坑
- WPF中控制窗口显示位置的三种方式
- 基于docker swarm和docker-compose搭建相异宿主机上的mysql和tomcat容器
- 正则表达式学习笔记
- UIScrollView