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

HDU 5869 Different GCD Subarray Query(数论+BIT)

2016-09-19 09:18 453 查看
Description

一个长度为n的序列a,m次查询,每次查询一个区间[l,r]的所有子区间的区间gcd中不同数的个数

Input

多组用例,每组用例第一行两个整数n和m表示序列长度和查询数,之后n个整数ai表示该序列,最后m行每行两个整数l,r表示查询区间(1<=n,m<=1e5,1<=ai<=1e6)

Output

对于每个查询,输出区间[l,r]的所有子区间的区间gcd中不同数的个数

Sample Input

5 3

1 3 4 6 9

3 5

2 5

1 5

Sample Output

6

6

6

Solution

区间gcd的典型特征就是固定左端点(或右端点)后,随着右端点(或左端点)右移(或左移),gcd的值至多log A种情况(A为端点值),首先预处理出任一点i作为右端点时区间gcd的所有情况,用一个二元组存gcd的值v以及使得gcd[l,i]=v的最大l值,对所有查询按右端点排序,从1到n枚举区间右端点,用树状数组维护当前出现的gcd值的左端点最大值,用一个pos数组记录每个gcd值对应的区间左端点最大值,每次遇见比pos值大的左端点就在树状数组中pos位置消除原先值新加当前值并更新pos,当i是某次查询的右端点即遇到一次查询[l,r]时,相当于是求树状数组中[l,r]的区间和,做两遍前缀和查询做差即可,时间复杂度O(nlognlogA)

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111111
int n,m,a[maxn],pos[10*maxn],ans[maxn];
typedef pair<int,int>P;
vector<P>v[maxn],q[maxn];
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
struct BIT
{
#define lowbit(x) (x&(-x))
int b[maxn<<1],N;
void init()
{
memset(b,0,sizeof(b));
}
void update(int x,int v)
{
while(x<=n)
{
b[x]+=v;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
}bit;
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
v[i].clear(),q[i].clear();
}
v[0].clear();
for(int i=1;i<=n;i++)
{
int x=a[i],y=i;
for(int j=0;j<v[i-1].size();j++)
{
int g=gcd(v[i-1][j].first,a[i]);
if(g!=x)
{
v[i].push_back(P(x,y));
x=g,y=v[i-1][j].second;
}
}
v[i].push_back(P(x,y));
}
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
q[y].push_back(P(x,i));
}
bit.init();
memset(pos,0,sizeof(pos));
for(int i=1;i<=n;i++)
{
for(int j=0;j<v[i].size();j++)
{
int g=v[i][j].first,p=v[i][j].second;
if(pos[g]<p)
{
if(pos[g])bit.update(pos[g],-1);
bit.update(p,1);
pos[g]=p;
}
}
for(int j=0;j<q[i].size();j++)
{
int l=q[i][j].first,id=q[i][j].second;
ans[id]=bit.query(i)-bit.query(l-1);
}
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: