NC13232 数列互质(莫队)

观察数据范围和题目意思,不难想到用莫队算法,之后暴力查询即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int N=2e5+10;
int cnt[N];
int vis[N];
int num[N];
int pos[N];
int a[N];
int ans[N];
map<int,int> m1;
struct node{
    int l,r;
    int k,id;
}q[N];
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
bool cmp(node a,node b){
    if(pos[a.l]==pos[b.l])
        return a.r<b.r;
    return pos[a.l]<pos[b.l];
}
void add(int x){
    cnt[a[x]]++;
    m1[a[x]]=cnt[a[x]];
}
void sub(int x){
    cnt[a[x]]--;
    m1[a[x]]=cnt[a[x]];
}
int check(int k){
    auto it=m1.begin();
    int res=0;
    for(;it!=m1.end();it++){
        int x=it->second;
        if(x!=0){
            if(gcd(x,k)==1)
                res++;
        }
    }
    return res;
}
int main(){
    int i;
    int n,m;
    cin>>n>>m;
    int block=sqrt(n);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        pos[i]=(i-1)/block+1;
    }
    for(i=1;i<=m;i++){
      scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
      q[i].id=i;
    }
    sort(q+1,q+1+m,cmp);
    int l=1,r=0;
    for(i=1;i<=m;i++){
        while(q[i].l<l)
            add(--l);
        while(q[i].l>l)
            sub(l++);
        while(q[i].r<r)
            sub(r--);
        while(q[i].r>r)
            add(++r);
        ans[q[i].id]=check(q[i].k);
    }
    for(i=1;i<=m;i++){
        printf("%d\n",ans[i]);
    }
}
View Code

 

posted @ 2020-03-25 16:40  朝暮不思  阅读(178)  评论(0编辑  收藏  举报