hdu 4630 No Pain No Game
2013-08-13 01:12
363 查看
题意:给出一个N和1到N的某个排列,询问Q次,每次询问[L,R]区间内任意挑两个数,最大公约数的最大值是多少。
离线处理每个查询,从左到右依次处理每个点,对于处理到的区间端点R,依次枚举R的因子,如果这个因子出现过,那么就将这个因子出现过的上一个位置,赋值为这个因子(当然,也要取较大值),同时,更新这个因子出现的位置为端点R。那么问题就转化成求终点在R的区间中最大值是多少了。
离线处理每个查询,从左到右依次处理每个点,对于处理到的区间端点R,依次枚举R的因子,如果这个因子出现过,那么就将这个因子出现过的上一个位置,赋值为这个因子(当然,也要取较大值),同时,更新这个因子出现的位置为端点R。那么问题就转化成求终点在R的区间中最大值是多少了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) const int N=50005; struct Segtree { int mx[N*4]; void PushUp(int ind) { mx[ind]=max(mx[LL(ind)],mx[RR(ind)]); } void build(int lft,int rht,int ind) { mx[ind]=0; if(lft!=rht) { int mid=MID(lft,rht); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); } } void updata(int pos,int valu,int lft,int rht,int ind) { if(lft==rht) mx[ind]=max(mx[ind],valu); else { int mid=MID(lft,rht); if(pos<=mid) updata(pos,valu,lft,mid,LL(ind)); else updata(pos,valu,mid+1,rht,RR(ind)); PushUp(ind); } } int query(int st,int ed,int lft,int rht,int ind) { if(st<=lft&&rht<=ed) return mx[ind]; else { int mid=MID(lft,rht); int mx1=0,mx2=0; if(st<=mid) mx1=query(st,ed,lft,mid,LL(ind)); if(ed> mid) mx2=query(st,ed,mid+1,rht,RR(ind)); return max(mx1,mx2); } } }seg; struct OP { int st,ed,id; OP(){} OP(int st,int ed,int id) : st(st),ed(ed),id(id) {} bool operator<(const OP &B)const { return ed<B.ed; } }op ; int n,m; int a ; int pre ; int res ; int main() { //freopen("4630.in","r",stdin); int t; 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=0;i<m;i++) { int st,ed; scanf("%d%d",&st,&ed); op[i]=OP(st,ed,i); } sort(op,op+m); seg.build(1,n,1); memset(pre,-1,sizeof(pre)); int ind=0; for(int i=1;i<=n;i++) { for(int j=1;j*j<=a[i];j++) if(a[i]%j==0) { if(pre[j]!=-1) { seg.updata(pre[j],j,1,n,1); } if(pre[a[i]/j]!=-1) { seg.updata(pre[a[i]/j],a[i]/j,1,n,1); } pre[j]=i; pre[a[i]/j]=i; } while(ind<m&&op[ind].ed==i) { int tmp=seg.query(op[ind].st,i,1,n,1); res[ op[ind].id ]=tmp; ind++; } } for(int i=0;i<m;i++) printf("%d\n",res[i]); } return 0; }
相关文章推荐
- hdu 4630 No Pain No Game
- hdu 4630 No Pain No Game(树状数组离线操作)
- hdu 4630 No Pain No Game(线段树)
- hdu 4630 No Pain No Game
- hdu 4630 No Pain No Game(线段树+离线操作)
- hdu 4630 No Pain No Game (区间gcd相关x线段树or树状数组)
- hdu 4630 No Pain No Game【线段树 离线操作】
- 2013多校联合3 1010 No Pain No Game(hdu 4630)
- HDU 4630 No Pain No Game 树状数组+离线查询
- HDU 4630 No Pain No Game (线段树离线查询)
- hdu 4630 No Pain No Game
- HDU-4630 No Pain No Game 树状数组+离线操作
- HDU-4630-No Pain No Game
- HDU 4630 No Pain No Game 树状数组+离线操作
- HDU - 4630 No Pain No Game (线段树 + 离线处理)
- HDU 4630 No Pain No Game(线段树离线处理)
- HDU 4630 No Pain No Game 解题报告
- hdu 4630 No Pain No Game
- HDU 4630 No Pain No Game(树状数组)
- HDU 4630 No Pain No Game(2013多校3 1010题 离线处理+树状数组求最值)