牛客13232 数列互质(莫队算法)

题意:

给出一串序列,每次询问区间内的有多少个数的出现数量和指定的数互质。

题解:

莫队暴力的时间复杂度好像没比暴力优化多少...

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
int a[maxn];
int cnt[maxn];
int belong[maxn];
int n,m,size,bnum,now,ans[maxn];
struct query {
    int l,r,id,k;
}q[maxn];
int cmp (query a,query b) {
    return (belong[a.l]^belong[b.l]?belong[a.l]<belong[b.l]:((belong[a.l]&1?a.r<b.r:a.r>b.r)));
} 
void add (int pos) {
    ++cnt[a[pos]];
}
void del (int pos) {
    --cnt[a[pos]];
}
int main () {
    scanf("%d%d",&n,&m);
    size=sqrt(n);
    set<int> st;
    bnum=n/size+(n%size>0);
    for (int i=1;i<=bnum;i++)
        for (int j=(i-1)*size;j<=i*size;j++)
            belong[j]=i;
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),st.insert(a[i]);
    for (int 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+m+1,cmp);
    int l=1,r=0;
    for (int i=1;i<=m;i++) {
        int ql=q[i].l;
        int qr=q[i].r;
        while (l<ql) del(l++);
        while (l>ql) add(--l);
        while (r<qr) add(++r);
        while (r>qr) del(r--);
        //ans[q[i].id]=now;
        now=0;
        for (auto it=st.begin();it!=st.end();it++)
            if (__gcd(cnt[*it],q[i].k)==1&&cnt[*it]) now++;
        ans[q[i].id]=now;
    }
    for (int i=1;i<=m;i++) printf("%d
",ans[i]);
}
原文地址:https://www.cnblogs.com/zhanglichen/p/13255218.html