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]); } }
没有人不辛苦,只有人不喊疼