您的位置:首页 > 产品设计 > UI/UE

hdu5869 Different GCD Subarray Query(预处理+树状数组)

2016-09-13 13:44 363 查看
Different GCD Subarray Query

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it looks, Bob cannot figure it out himself. Now he turns to you for help, and here is the problem:

Given an array a of N positive integers a1,a2,⋯aN−1,aN; a subarray of a is defined as a continuous interval between a1 and aN. In other words, ai,ai+1,⋯,aj−1,aj is a subarray of a, for 1≤i≤j≤N. For a query in the form (L,R), tell the number of different GCDs contributed by all subarrays of the interval [L,R].

Input

There are several tests, process till the end of input.

For each test, the first line consists of two integers N and Q, denoting the length of the array and the number of queries, respectively. N positive integers are listed in the second line, followed by Q lines each containing two integers L,R for a query.

You can assume that

1≤N,Q≤100000


1≤ai≤1000000

Output

For each query, output the answer in one line.

Sample Input

5 3

1 3 4 6 9

3 5

2 5

1 5

Sample Output

6

6

6

题解:

感觉自己这道题还没有完全理解透彻,现放这里把,代码的实现是照着别人的代码写的,以后再来反复体会。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;

int n,Q;
int A[maxn];
vector<pair<int,int> >vec[maxn];

int used[maxn*10];
pair<int,pair<int,int> > Ans[maxn];

int ANS[maxn];
int Seg[maxn];

void UPDATA(int now,int val) {
while(now<maxn) {
Seg[now]+=val;
now+=(now&(-now));
}
}

int SUM(int now) {
int ans=0;
while(now>0) {
ans+=Seg[now];
now-=(now&(-now));
}
return ans;
}
int main() {
#ifdef tangge
freopen("5869.in","r",stdin);
#endif // tangge
int u,v;
vec[0].clear();
while(scanf("%d%d",&n,&Q)==2) {
for(int i=1; i<=n; ++i) {
scanf("%d",&A[i]);
vec[i].clear();
}
for(int i=1; i<=n; ++i) {
int Gcd=A[i],len=(int)vec[i-1].size(),Pos=i;
for(int j=0; j<len; ++j) {
int nowGcd=__gcd(Gcd,vec[i-1][j].first);
if(nowGcd!=Gcd) {
vec[i].push_back(make_pair(Gcd,Pos));
Gcd=nowGcd,Pos=vec[i-1][j].second;
}
}
vec[i].push_back(make_pair(Gcd,Pos));
}
for(int i=0; i<Q; ++i) {
scanf("%d%d",&Ans[i].second.first,&Ans[i].first);
Ans[i].second.second=i;
}
sort(Ans,Ans+Q);
memset(used,0,sizeof(used));
int nowAnsPos=0;
memset(Seg,0,sizeof(Seg));
for(int i=1; i<=n; ++i) {
int len=(int)vec[i].size();
for(int j=0; j<len; ++j) {
int nowGCD=vec[i][j].first,lastPos=vec[i][j].second;
if(used[nowGCD])
UPDATA(used[nowGCD],-1);
UPDATA(lastPos,1);
used[nowGCD]=lastPos;
}
while(nowAnsPos<Q&&Ans[nowAnsPos].first==i) {
ANS[Ans[nowAnsPos].second.second]=
SUM(Ans[nowAnsPos].first)-SUM(Ans[nowAnsPos].second.first-1);
++nowAnsPos;
}
}
for(int i=0; i<Q; ++i) {
printf("%d\n",ANS[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: