首页 > 其他 > 详细

HDU-5869 Different GCD Subarray Query

时间:2017-02-04 19:55:22      阅读:228      评论:0      收藏:0      [点我收藏+]

Different GCD Subarray Query

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1202    Accepted Submission(s): 450

 

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 1ijN. 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 
  
    1N,Q100000 
    
   1ai1000000
 

 

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值。

这道题和HDU-3333非常像。区别在于这里需要处理的是gcd。而gcd有一个性质,即相同起点的序列的gcd非严格递减。

对比HDU-3333,这道题需要使每个gcd对应序列的左起点尽量向右。

扫描到位置i的时候,可以新得到的gcd只与前面的i-1个数有关,但事实上能产生的新gcd是有限的,大概有\( \log a_i \)个。所以用gcds[][]存起来,每次用gcd[i-1]更新gcd[i]即可。

 

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 
 5 #define MAXN 100010
 6 #define MAXM 100010
 7 
 8 int gcd(int a,int b)
 9 {
10     if(b==0) return a;
11     return gcd(b,a%b);
12 }
13 int d[MAXN];
14 int n,m;
15 vector<pair<int,int> > q[MAXM];
16 vector<pair<int,int> > gcds[MAXN];
17 int vis[1000010];
18 int ans[MAXM];
19 int tree[MAXN];
20 int lowbit(int x)
21 {
22     return x&(-x);
23 }
24 void add(int k,int num)
25 {
26     while(k<=n)
27     {
28         tree[k]+=num;
29         k+=lowbit(k);
30     }
31 }
32 int sum(int k)
33 {
34     int ans=0;
35     while(k)
36     {
37         ans+=tree[k];
38         k-=lowbit(k);
39     }
40     return ans;
41 }
42 int main()
43 {
44 #ifdef LOCAL
45     freopen("in.txt","r",stdin);
46 #endif
47     while(scanf("%d%d",&n,&m)!=EOF)
48     {
49         for(int i=0;i<=n;i++) gcds[i].clear();
50         for(int i=1;i<=n;i++) q[i].clear();
51         memset(vis,0,sizeof(vis));
52         memset(tree,0,sizeof(tree));
53         for(int i=1;i<=n;i++) scanf("%d",&d[i]);
54         for(int i=1;i<=m;i++)
55         {
56             int l,r;
57             scanf("%d%d",&l,&r);
58             q[r].push_back(make_pair(l,i));
59         }
60         for(int i=1;i<=n;i++)
61         {
62             if(vis[d[i]]) add(vis[d[i]],-1);
63             add(i,1);
64             vis[d[i]]=i;
65             gcds[i].push_back(make_pair(d[i],i));
66             for(unsigned int j=0;j<gcds[(i-1)].size();j++)
67             {
68                 int tmp1=gcd(gcds[(i-1)][j].first,d[i]),tmp2=gcds[(i-1)][j].second;
69                 if(tmp1==gcds[i][gcds[i].size()-1].first) continue;
70                 if(vis[tmp1]) add(vis[tmp1],-1);
71                 add(tmp2,1);
72                 vis[tmp1]=tmp2;
73                 gcds[i].push_back(make_pair(tmp1,tmp2));
74             }
75             for(unsigned int j=0;j<q[i].size();j++)
76             {
77                 int tmp=q[i][j].second;
78                 ans[tmp]=sum(i)-sum(q[i][j].first-1);
79             }
80         }
81         for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
82     }
83     return 0;
84 }

 

 

HDU-5869 Different GCD Subarray Query

原文:http://www.cnblogs.com/zarth/p/6366182.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!