首页 > 代码库 > No Pain No Game
No Pain No Game
hdu4630:http://acm.hdu.edu.cn/showproblem.php?pid=4630
题意:给定一个排序,求区间最大GCD。
题解:离散树状数组。首先把查询按左端点从大到小排序。然后用树状数组来维护每个位置出现的最大的公约数。枚举每个数的约数,记录到当前位置为止,上一个x的倍数出现的位置b[x];
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<vector> 6 using namespace std; 7 const int N=5e4+19; 8 int a[N],c[N],b[N],ans[N]; 9 int n,m;10 int lowbit(int x){11 return x&(-x);12 }13 void add(int x,int val){14 while(x<=n){15 c[x]=max(c[x],val);16 x+=lowbit(x);17 }18 }19 int getsum(int x){20 int sum=0;21 while(x>0){22 sum=max(sum,c[x]);23 x-=lowbit(x);24 }25 return sum;26 }27 struct Node{28 int l,r;29 int id;30 bool operator<(const Node a)const{31 return l>a.l;32 }33 }num[N];34 int main(){35 int T;36 scanf("%d",&T);37 while(T--){38 scanf("%d",&n);39 memset(a,0,sizeof(a));40 memset(c,0,sizeof(c));41 memset(b,0,sizeof(b));42 for(int i=1;i<=n;i++)43 scanf("%d",&a[i]);44 scanf("%d",&m);45 for(int i=1;i<=m;i++){46 scanf("%d%d",&num[i].l,&num[i].r);47 num[i].id=i;48 }49 sort(num+1,num+m+1);50 int j=n;51 for(int i=1;i<=m;i++){52 for(;j>=num[i].l;j--){53 for(int k=1;k*k<=a[j];k++){54 if(a[j]%k==0){55 if(b[k]){56 add(b[k],k);57 }58 b[k]=j;59 if(k*k!=a[j]){60 if(b[a[j]/k]){61 add(b[a[j]/k],a[j]/k);62 }63 b[a[j]/k]=j;64 }65 }66 }67 }68 ans[num[i].id]=getsum(num[i].r);69 }70 for(int i=1;i<=m;i++)71 printf("%d\n",ans[i]);72 }73 }
No Pain No Game
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。