传送门
虽然看了下题目知道是考数据结构了,但是不知道怎么做。后来才明白。。。
这里用树状数组做,先输入所有要输入的,然后离线做,这样可以将问询排序,然后在跟新树状数组的时候选择恰到好处的时机进行查询。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[50005]; int d[50005][150]; int t,n,m,x,y,u,k; int pre[50005]; int ans[50005]; struct Query { int l,r; int id; }q[50005]; int c[50005]; void init() { memset(d,0,sizeof(d)); for(int i=1;i<50003;i++) { for(int j=i;j<50003;j+=i)d[j][++d[j][0]]=i; } } bool cmp(Query q1,Query q2) { return q1.r<q2.r; } void update(int st,int val) { for(int i=st;i<=n;i+=(i&(-i))) { c[i]=max(c[i],val); } } int query(int lt) { int s=0; for(int i=lt;i>0;i-=(i&(-i))) { s=max(s,c[i]); } return s; } int main() { init(); scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); q[i].l=x; q[i].r=y; q[i].id=i; } sort(q+1,q+m+1,cmp); memset(c,0,sizeof(c)); memset(pre,0,sizeof(pre)); k=1; for(int i=1;i<=n;i++) { for(int j=1;j<=d[a[i]][0];j++) { u=d[a[i]][j]; if(pre[u]!=0)update(n-pre[u]+1,u); pre[u]=i; } while(q[k].r==i&&k<=m) { ans[q[k].id]=query(n-q[k].l+1); k++; } } for(int i=1;i<=m;i++)cout<<ans[i]<<endl; } return 0; }