HDU 5726 GCD (ST 表 +查询)
传送门: 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): 4341 Accepted Submission(s): 1550
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
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
123
题意 : 给 n 个数 m 次查询 问 从 a-b GCD是多少 并且问 你 在 整个n区间内 GCD = GCD(a,b)的 有多少个;
10w 的数据 QMR查询 利用ST 动态 打表, 求GCD
二分从 1-n 存取 GCD的相等的数目:
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <cstring> #include <string> #include <queue> #include <stack> #include <stdlib.h> #include <list> #include <map> #include <set> #include <bitset> #include <vector> #define mem(a,b) memset(a,b,sizeof(a)) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w",stdout) #define S1(n) scanf("%d",&n) #define SL1(n) scanf("%I64d",&n) #define S2(n,m) scanf("%d%d",&n,&m) #define SL2(n,m) scanf("%I64d%I64d",&n,&m) #define Pr(n) printf("%d\n",n) using namespace std; typedef long long ll; const double PI=acos(-1); const int INF=0x3f3f3f3f; const double esp=1e-6; const int maxn=1e5+5; const int MOD=1e9+7; const int mod=1e9+7; int dir[5][2]={0,1,0,-1,1,0,-1,0}; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;} ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;} ll lcm(ll a,ll b){ return b/gcd(a,b)*a;} ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;} int n; ll a[maxn]; ll maps[maxn][25]; void ST() { for(int i=1;i<=n;i++) maps[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++) maps[i][j]=gcd(maps[i][j-1],maps[i+(1<<j-1)][j-1]); } ll get_gcd(int l,int r) { if(l>r)swap(l,r); int x= int (log(r-l+1)/log(2)); return gcd(maps[l][x],maps[r-(1<<x)+1][x]); } int main() { int T; S1(T); int cont=0; while(T--) { S1(n); mem(a,0); mem(maps,0); for(int i=1;i<=n;i++) S1(a[i]); map<ll,ll>mp; ST(); for(int i=1;i<=n;i++) { ll val= a[i]; int pos =i; while(pos<=n) { //cout<<"pos "<<pos<<endl; int l=pos; int r=n; val=get_gcd(i,pos); while(r>l) { int mid=(l+r+1)>>1; if(get_gcd(i,mid)==val) l=mid; else r=mid-1; } mp[val]+=(l-pos)+1; pos=l+1; } } int m; printf("Case #%d:\n",++cont); cin>>m; int x,y; while(m--) { scanf("%d %d",&x,&y); ll ans=get_gcd(x,y); printf("%lld %lld\n",ans,mp[ans]); } } return 0; }
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!