标签:
题意:
给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值
分析:
有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过,那这个约数可能就是最大的答案。所以我们枚举当前数的所有约数,用线段树维护区间最大值,查询序列离线处理保证查询的正确。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<1|1 #define All 1,N,1 #define N 50010 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; //bef当前数的约数前一次出现的位置 int maxv[N*4],n,bef[N],e,a[N],maxn[N]; struct que{ int l,r,id; }q[N]; bool cmp(que x,que y){ return x.r<y.r; } void pushup(int rt){ maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]); } void build(int l,int r,int rt){ maxv[rt]=1; if(l==r)return; int m=(l+r)>>1; build(lson); build(rson); } void update(int p,int v,int l,int r,int rt){ if(l==r){ maxv[rt]=max(maxv[rt],v); return; } int m=(l+r)>>1; if(p<=m)update(p,v,lson); else update(p,v,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ return maxv[rt]; } int m=(l+r)>>1; int num=0; if(L<=m)num=max(num,query(L,R,lson)); if(R>m)num=max(num,query(L,R,rson)); return num; } void solve(){ sort(q+1,q+e+1,cmp); memset(bef,0,sizeof(bef)); build(1,n,1); int b=1; for(int i=1;i<=n;++i){ for(int j=1;j*j<=a[i];j++){ if(a[i]%j==0){ if(bef[j]){ update(bef[j],j,1,n,1); } int tmp=a[i]/j; if(bef[tmp]&&tmp!=j) update(bef[tmp],tmp,1,n,1); bef[j]=i; bef[tmp]=i; } } while(b<=e&&q[b].r==i){ if(q[b].l==q[b].r) maxn[q[b].id]=0; else{ maxn[q[b].id]=query(q[b].l,q[b].r,1,n,1); } b++; } } for(int i=1;i<=e;++i) printf("%d\n",maxn[i]); } int main() { int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); scanf("%d",&e); for(int i=1;i<=e;++i){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } solve(); } return 0; }
HDU 4630-No Pain No Game(线段树+离线处理)
标签:
原文地址:http://www.cnblogs.com/zsf123/p/4734957.html