http://acm.hdu.edu.cn/showproblem.php?pid=5726
两种做法,一个是仿照hdu5869 的那种做法,好写很多,复杂度也较优,不得不说那个思维很强
1575ms
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<pair<int,int> >w[maxn];
int a[maxn];
map<int,long long>p;
void init(int x)
{
p.clear();
for(int i=0;i<=x;i++)
w[i].clear();
return ;
}
int main()
{
int T,n,Q,i,j,tca=1;
cin>>T;
while(T--)
{
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=n;i++)
{
int pre=-1;
for(j=0;j<w[i-1].size();j++)
{
int temp=__gcd(w[i-1][j].second,a[i]);
if(temp!=pre)
{
w[i].push_back(make_pair(w[i-1][j].first,temp));
}
pre=temp;
}
w[i].push_back(make_pair(i,a[i]));
p[a[i]]++;
for(j=1;j<w[i].size();j++)
{
p[w[i][j-1].second]+=w[i][j].first-w[i][j-1].first;
}
}
cin>>Q;
int l,r;
printf("Case #%d:\n",tca++);
while(Q--)
{
scanf("%d %d",&l,&r);
if(l==r)
{
printf("%d %lld\n",a[r],p[a[r]]);
}
else
{
for(i=0;i<w[r].size();i++)
{
if(l<w[r][i].first)
{
printf("%d %lld\n",w[r][i-1].second,p[w[r][i-1].second]);
break;
}
}
}
}
init(n);
}
return 0;
}
第二个种是st表预处理区间gcd,然后二分
因为确定左区间后,对于所有的右区间端点,最多有log(a【l】)个不同的gcd
这样就可以枚举左区间,对于一个左区间,不断的二分移动确定不同gcd值的最大右区间
2121ms
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int s[maxn];
int dp[maxn][30];
map<int,long long>p;
int n;
void RMQ_init()
{
for(int i=1;i<=n;i++)
dp[i][0]=s[i];
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i+(1<<j)-1<=n;i++)
{
dp[i][j]=__gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int RMQ(int l,int r)
{
int k=0;
while((1<<(k+1))<=r-l+1)k++;
return __gcd(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
int T,i,j,Q,tca=1;
cin>>T;
while(T--)
{
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%d",&s[i]);
}
RMQ_init();
p.clear();
for(i=1;i<=n;i++)
{
int now=i;
// cout<<i<<" :"<<endl;
while(1)
{
int l=now,r=n,mid;
int temp=RMQ(i,now);
while(l<=r)
{
mid=(l+r)>>1;
if(RMQ(i,mid)>=temp)
{
l=mid+1;
}
else
{
r=mid-1;
}
}
// cout<<l<<endl;
p[temp]+=l-now;
now=l;
if(l-1>=n)
break;
}
}
cin>>Q;
printf("Case #%d:\n",tca++);
int l,r;
while(Q--)
{
scanf("%d %d",&l,&r);
int temp=RMQ(l,r);
printf("%d %lld\n",temp,p[temp]);
}
}
return 0;
}