「codechefSUBLCM」Subarray LCM
题解
首先筛法求100w以内的素数,同时记录每个质数最小的质因数
然后用last[x]记录质因数x的最后出现位置,用tmp表示max{i}(满足i到当前位置now间的所有数互质)
每次读入一个数a[now],对a[now]分解质因数,更新tmp,更新last[x]
tmp=max(tmp,last[t]);
last[t]=i;
最后用i-tmp更新答案
我表达能力极弱啊。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<set> #define inf 1000000000 #define ll long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int T,n,tot,ans,tmp; int pri[1000005]; int last[1000005],a[1000005]; int mn[1000005]; void getpri() { for(int i=2;i<=1000000;i++) { if(!mn[i]) { mn[i]=i; pri[++tot]=i; } for(int j=1;j<=tot&&pri[j]*i<=1000000;j++) { mn[pri[j]*i]=pri[j]; if(i%pri[j]==0)break; } } } int main() { getpri(); T=read(); while(T--) { memset(last,0,sizeof(last)); n=read(); ans=tmp=0; for(int i=1;i<=n;i++) { int x=read(); while(x!=1) { int t=mn[x]; tmp=max(tmp,last[t]); last[t]=i; while(x%t==0)x/=t; } ans=max(ans,i-tmp); } if(ans!=1)printf("%d\n",ans); else puts("-1"); } return 0; } |
Subscribe