link : https://loj.ac/problem/6164
莫队傻题,直接容斥做。
#include<bits/stdc++.h> #define maxn 100005 #define pb push_back using namespace std; vector<int> g[maxn]; struct ask{ int l,r,K,num,bl; bool operator <(const ask &u)const{ return bl==u.bl?((bl&1)?r<u.r:r>u.r):bl<u.bl; } }q[maxn]; int a[maxn],n,m; int num[maxn],sz,cnt[maxn]; int ans[maxn],d[10],ci[30]; int tot,mul[2905],jc[2905]; inline void init(){ ci[0]=1; for(int i=1;i<=20;i++) ci[i]=ci[i-1]<<1; for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i) g[j].pb(i); mul[0]=1; for(int i=1;i<=2900;i++) mul[i]=-mul[i^(i&-i)]; } inline int calc(int O){ tot=0; for(int i=2;i*i<=O;i++) if(!(O%i)){ d[tot++]=i; while(!(O%i)) O/=i; if(O==1) break; } if(O!=1) d[tot++]=O; int an=0; jc[0]=1; for(int i=0;i<tot;i++) jc[ci[i]]=d[i]; for(int i=0,p;i<ci[tot];i++){ p=i^(i&-i); if(p) jc[i]=jc[p]*jc[i^p]; an+=mul[i]*num[jc[i]]; } return an; } inline void add(int O){ for(int i=g[O].size()-1;i>=0;i--){ num[g[O][i]]++; } } inline void del(int O){ for(int i=g[O].size()-1;i>=0;i--){ num[g[O][i]]--; } } inline void solve(){ int le=1,ri=0; for(int i=1;i<=m;i++){ while(ri<q[i].r) ri++,del(cnt[a[ri]]),cnt[a[ri]]++,add(cnt[a[ri]]); while(ri>q[i].r) del(cnt[a[ri]]),cnt[a[ri]]--,add(cnt[a[ri]]),ri--; while(le>q[i].l) le--,del(cnt[a[le]]),cnt[a[le]]++,add(cnt[a[le]]); while(le<q[i].l) del(cnt[a[le]]),cnt[a[le]]--,add(cnt[a[le]]),le++; ans[q[i].num]=calc(q[i].K); } } int main(){ scanf("%d%d",&n,&m); init(),sz=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=m;i++){ scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].K); q[i].num=i,q[i].bl=(q[i].l-1)/sz+1; } sort(q+1,q+m+1); solve(); for(int i=1;i<=m;i++) printf("%d ",ans[i]); return 0; }