概述
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5869
题意:给定一个数组,给出范围[l,r],求在这范围内的不同gcd值得个数(连续下标)
题解:用o(nlogA)计算出gcd值并进行记录,每次固定右值,枚举前一个得出的gcd值,记录左边的坐标和不同gcd值,然后用树状数组维护,具体见注释
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define MAX 100500
using namespace std;
int c[MAX];
int number[MAX];
int ans[MAX];
vector<pair<int,int> > value[MAX]; 每个点击记录从1--i的gcd值,first表示gcd值,second表示second--m的范围的左值
typedef struct
{
int l,r;
int position;
}Adress;
Adress ad[MAX];
int vis[1000050];
bool compare(Adress a,Adress b)
{
return a.r<b.r;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
for(int i=x;i<=MAX;i+=lowbit(i))
{
c[i]+=v;
}
}
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}
long long sum(int x)
{
long long sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int n,q;
while(~scanf("%d %d",&n,&q))
{
for(int i=1;i<=n;i++)
{
scanf("%d",&number[i]);
value[i].clear();
}
for(int i=1;i<=n;i++)//遍历每个点
{
int num=number[i],id=i;
for(int j=0;j<value[i-1].size();j++)//根据前一个点的gcd记录值来进行当前点的计算,即每次固定右值,遍历左值
{
int _gcd=gcd(max(num,value[i-1][j].first),min(num,value[i-1][j].first));
if(_gcd != num)//防止重复
{
value[i].push_back(make_pair(num,id));
num=_gcd;id=value[i-1][j].second;
}
}
value[i].push_back(make_pair(num,id));
}
for(int i=1;i<=q;i++)
{
scanf("%d %d",&ad[i].l,&ad[i].r);
ad[i].position=i;
}
sort(ad+1,ad+1+q,compare);
memset(c,0,sizeof(c));
memset(vis,0,sizeof(vis));
int cnt=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<value[i].size();j++)//维护树状数组
{
int num=value[i][j].first;
int id=value[i][j].second;
if(vis[num]) add(vis[num],-1);
vis[num]=id;
add(id,1);
}
while(ad[cnt].r==i&&cnt<=q)//得出结论
{
ans[ad[cnt].position]=sum(ad[cnt].r)-sum(ad[cnt].l-1);cnt++;
}
if(cnt>q) break;
}
for(int i=1;i<=q;i++)
{
printf("%dn",ans[i]);
}
}
return 0;
}
最后
以上就是舒服薯片为你收集整理的离线记录+树状数组(hdu 5869 统计任意区间的不同gcd值)的全部内容,希望文章能够帮你解决离线记录+树状数组(hdu 5869 统计任意区间的不同gcd值)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复