Description

给定一个长度为 \(n\) 的序列,有 \(q\) 组询问,每次询问给定一个下标区间 \([l,r]\),问这个区间中,有多少数可以整除区间中的所有数。

Solution

对于区间 \([l,r]\)\(a_i\) 整除所有数即 \(a_i | \textrm{gcd}(a_l,a_{l+1},...,a_r)\)

\(g=\textrm{gcd}(a_l,a_{l+1},...,a_r)\),可以用线段树在 \(O(\log n)\) 时间内求出

\(a_i | g \and a_i \le g \Rightarrow a_i = g\),于是只需要统计区间中等于 \(g\) 的个数即可

对所有数字离散化后,对每种数用 vector 存储其出现位置,查询时在 vector 上二分即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;
const int dbg = 0;

int n,q,t1,t2,t3,l,r;
int a[N];

int gcd(int x,int y)
{
    return __gcd(x,y);
}

namespace seg
{
int a[N];

void build(int p,int l,int r,int *src)
{
    if(l==r)
    {
        a[p]=src[l];
    }
    else
    {
        build(p*2,l,(l+r)/2,src);
        build(p*2+1,(l+r)/2+1,r,src);
        a[p]=gcd(a[p*2],a[p*2+1]);
    }
}

int query(int p,int l,int r,int ql,int qr)
{
    if(l>qr || r<ql) return 0;
    if(l>=ql && r<=qr) return a[p];
    return gcd(query(p*2,l,(l+r)/2,ql,qr), query(p*2+1,(l+r)/2+1,r,ql,qr));
}
}

namespace cnter
{
map <int,int> mp;
int imp[N];
int ind=0;
vector <int> vec[N];

void init()
{
    for(int i=1;i<=n;i++) mp[a[i]]++;
    for(auto &i:mp) i.second=++ind, imp[ind]=i.first;
    for(int i=1;i<=n;i++) vec[mp[a[i]]].push_back(i);
}

int query(int l,int r,int key)
{
    int pos=mp[key];
    if(pos)
    {
        vector <int> &v = vec[pos];
        auto it1=lower_bound(v.begin(),v.end(),l);
        auto it2=lower_bound(v.begin(),v.end(),r+1);
        return it2-it1;
    }
    else return 0;
}
}

signed main()
{
    ios::sync_with_stdio(false);

    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    seg::build(1,1,n,a);
    cnter::init();
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        cin>>l>>r;
        int g=seg::query(1,1,n,l,r);
        if(dbg) cout<<" g = "<<g<<endl;
        int ans=cnter::query(l,r,g);
        cout<<r-l+1-ans<<endl;
    }
}

相关文章:

  • 2021-07-18
  • 2022-12-23
  • 2021-07-22
  • 2022-02-25
  • 2021-08-26
  • 2021-09-28
  • 2022-12-23
  • 2021-12-05
猜你喜欢
  • 2021-06-28
  • 2021-09-04
  • 2021-08-08
  • 2022-02-02
  • 2021-12-11
  • 2022-12-23
  • 2021-08-25
相关资源
相似解决方案