【HDU 5726】GCD
题目戳这里
题目描述
Give you a sequence ofN(N≤100,000)integers :a1,...,an(0<ai≤1000,000,000). There areQ(Q≤100,000)queries. For each queryl,ryou have to calculategcd(al,,al+1,...,ar)and count the number of pairs(l′,r′)(1≤l<r≤N)such thatgcd(al′,al′+1,...,ar′)equalgcd(al,al+1,...,ar).
解题思路
代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; int t,n,q; int a[100050],st[100050][25]; int loooog[100050]; map<int,long long>ans; inline void read(int &x){ x=0; register char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); } inline int gcd(int x,int y){ return x==0?y:gcd(y%x,x); } inline int query(int x,int y){ int z=loooog[y-x+1]; return gcd(st[x][z],st[y-(1<<z)+1][z]); } inline void solve(int x,int y){ int temp=query(x,y); printf("%d ",temp); printf("%lld\n",ans[temp]); } int main(){ loooog[0]=-1; for(register int i=1;i<=100000;i++)loooog[i]=loooog[i>>1]+1; read(t); for(register int fuck=1;fuck<=t;fuck++){ read(n); memset(st,0,sizeof(st)); ans.clear(); for(register int i=1;i<=n;i++){ read(a[i]); st[i][0]=a[i]; } read(q); printf("Case #%d:\n",fuck); int N=loooog[n]+1; for(register int i=1;i<=N;i++){ for(register int j=1;j<=n-(1<<i)+1;j++){ st[j][i]=gcd(st[j][i-1],st[j+(1<<(i-1))][i-1]); } } for(register int i=1;i<=n;i++){ register int now=i,temp=a[i]; for(;now<=n;){ int l=now,r=n; while(l<r){ int m=(l+r+1)>>1; if(query(i,m)==temp)l=m; else r=m-1; } if(ans[temp])ans[temp]+=(l-now+1); else ans[temp]=(l-now+1); now=l+1,temp=gcd(temp,a[l+1]); } } register int l,r; for(register int i=1;i<=q;i++){ read(l),read(r); solve(l,r); } } }