思路: 利用莫队,对每一个数列的元素的质因数(利用欧拉筛法)进行处理(类似众数的处理)
莫队易错: 我的 add ,del 是 元素 i 的 而不是 val【i】的 ,不要搞错了,mdddd。
G. Magic Number Group time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Tsiying has a sequence of positive integers with a length of n and quickly calculates all the factors of each number. In order to exercise his factor calculation ability, he has selected q consecutive subsequences from the sequence and found a positive integer p greater than 1 for each subsequence, so that p can divide as many numbers in this subsequence as possible. He has also found that p may have more than one. So the question is, how many numbers in each subsequence can be divided at most? Input The first line contains an integer T (1≤T≤5×104), indicating that there is T test cases next. The first line of each test cases has two positive integers n (1≤n≤5×104), q (1≤q≤5×104). Next line n integers ai (1≤i≤n,1≤ai≤1×106), which representing the numbers in this sequence. The two adjacent numbers are separated by a space. Each of the next q lines contains two integers l,r (1≤l≤r≤n), representing a subsequence being queried, al,al+1,⋯,ar, and l,r are separated by a space. The input guarantees that the sum of n does not exceed 5×104 and the sum of q does not exceed 5×104. Output For each test case, output q lines, each line contains a positive integer, indicating the answer. Example inputCopy 1 10 5 20 15 6 1 21 12 2 3 17 9 1 4 2 5 3 6 4 7 5 10 outputCopy 2 3 3 2 4
#include <bits/stdc++.h> using namespace std; #define ri register int #define M 1000005 template <class G > void read(G &x) { x=0;int f=0;char ch=getchar(); while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} x=f?-x:x; return ; } struct dain{ int l,r,id,pos; bool operator <(const dain &t) const { if(pos==t.pos) { if(r==t.r) return l<t.l; return r<t.r; } return pos<t.pos; } }p[M]; int val[M]; int mx; int T,n,m; int prism[M],isprism[M]; int qu[M]; void init() { int r=0; for(ri i=2;i<=1e6;i++) { if(!isprism[i]) { qu[++r]=i; isprism[i]=i; } for(ri j=1;j<=r&&qu[j]*i<=1e6;j++) { isprism[qu[j]*i]=qu[j]; if(i%qu[j]==0) break; } } } int dp[M],num[M]; void add(int a) { a=val[a]; while(isprism[a]) { int tmp=isprism[a]; while(tmp==isprism[a]) { a/=isprism[a]; } num[tmp]++; dp[num[tmp]]++; dp[num[tmp]-1]--; mx=max(mx,num[tmp]); } } void del(int a) { a=val[a]; while(isprism[a]) { int tmp=isprism[a]; while(tmp==isprism[a]) { a/=tmp; } if(dp[num[tmp]]==1&&mx==num[tmp]) { mx--; } dp[num[tmp]]--; dp[--num[tmp]]++; } } int ans[M]; int main(){ init(); read(T); while(T--){ read(n);read(m); for(ri i=1;i<=n;i++) { read(val[i]); } int d=int(sqrt(n)+0.5); for(ri i=1;i<=m;i++) { int a,b; read(a);read(b); p[i].l=a;p[i].r=b; p[i].pos=a/d;p[i].id=i; } sort(p+1,p+1+m); int l=1,r=1;mx=0; add(1); /// attention for(ri i=1;i<=m;i++) { while(l<p[i].l) del(l++); while(r<p[i].r) add(++r); while(l>p[i].l) add(--l); while(r>p[i].r) del(r--); ans[p[i].id]=mx; } for(ri i=1;i<=m;i++) { printf("%d\n",ans[i]); } for(ri i=p[m].l;i<=p[m].r;i++) { del(i); } } return 0; }
学到了:莫队的预处理:直接add(1),l=r=1;