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

Different GCD Subarray Query (离线的处理)

2016-09-11 15:37 351 查看
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

题解:考虑固定左端点的不同GCD值,只有不超过logA种, 所以事件点只有nlogA个. 那么离线处理, 按照区间右端点排序从小到大处理询问,

用一个树状数组维护每个GCD值的最大左端点位置即可. 复杂度是O(nlogAlogn).

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include <vector>
#include <queue>
using namespace std;

#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f

int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int T;

int n,m;

int a[120000];

int cnt=0;

struct Node
{
int num,id;
Node(){}
Node(int l,int id):num(l),id(id){}
} ;

vector<Node> L[120000];
vector<Node> que[120000];

int ans[120000];

int c[1200000];
int pp[1200000];

int N=1200000;

int lowbit(int x){return x&(-x);}

void add(int x,int val)
{
while(x<N)
{
c[x]+=val;
x+=lowbit(x);
}
}

int sum(int x)
{
if(x<0) return 0;

int re=0;
while(x)
{
re+=c[x];
x-=lowbit(x);
}
return re;
}

void init()
{
for(int i=1;i<=n;i++)
{
int x=a[i],y=i;
L[i].push_back(Node(x,y));

for(int j=0;j<L[i-1].size();j++)
{
int now = gcd(a[i],L[i-1][j].num),pos = L[i-1][j].id;

if(now!=x)
{
L[i].push_back(Node(now,pos));
x=now;
}
}
}
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
L[i].clear();
que[i].clear();
}

init();
memset(c,0,sizeof(c));
memset(pp,0,sizeof(pp));

int l,r;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l,&r);
que[r].push_back(Node(l,i));
}

for(int i=1;i<=n;i++)
{
for(int j=0;j<L[i].size();j++)
{
int num = L[i][j].num,pos = L[i][j].id;

if(pp[num]) add(pp[num],-1);
pp[num]=pos;
add(pp[num],1);

}

for(int j=0;j<que[i].size();j++)
{
int num = que[i][j].num,id = que[i][j].id;
ans[id] = sum(i) - sum(num-1);
}
}

for(int i=1;i<=m;i++) printf("%d\n",ans[i]);

}
return 0;
}


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: