题目大意:给你一个无序的1~n的排列a,每次询问[l,r]之间任取两个数得到的最大gcd是多少

先对所有询问离线,然后把问题挂在区间的左端点上(右端点也行)

在预处理完质数,再处理一个next数组,表示 i 的任意一个质因子,这样我们分解质因数的时间降低到而不是

因为能对答案产生贡献的都是成对出现的两个数

所以每次记录一个last[i],表示数 i 上一次出现的位置

当遍历到第 i 个数时,分解出它的所有质因数,然后搜出它所有的因子,因子个数大约不会超过,均摊下来就更少了

那么,a[i] 的某个因数 x 就能和 last[x]成为一对,在线段树里的last[x]位置更新答案,即gcd(a[i],a[last[x]]),但不一定是last[x]的最优解,要在last[x]的位置取一个max

询问就是线段树里查询[l,r]的最大值

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 #define N 50010
  5 #define M 50
  6 #define ll long long
  7 using namespace std;
  8
  9 int n,q,cte,num,nson,T;
 10 int a[N],pr[N],nxt[N],use[N],head[N];
 11 int son[N],d[N],app[N],pw[N],la[N];
 12 struct node{int l,r,id,ans;}Q[N];
 13 struct Edge{int to,nxt;}edge[N];
 14 void ae(int u,int v){
 15 cte++;edge[cte].to=v;edge[cte].nxt=head[u];head[u]=cte;}
 16 int gcd(int x,int y){if(y==0)return x;return gcd(y,x%y);}
 17 struct Seg{
 18     #define il inline
 19     int ma[N<<2];
 20     il void pushup(int rt){ma[rt]=max(ma[rt<<1],ma[rt<<1|1]);}
 21     void build(int l,int r,int rt)
 22     {
 23         if(l==r) {ma[rt]=1;return;}
 24         int mid=(l+r)>>1;
 25         build(l,mid,rt<<1),build(mid+1,r,rt<<1|1);
 26         pushup(rt);
 27     }
 28     void update(int x,int l,int r,int rt,int w)
 29     {
 30         if(l==r){ma[rt]=max(ma[rt],gcd(w,a[l]));return;}
 31         int mid=(l+r)>>1;
 32         if(x<=mid) update(x,l,mid,rt<<1,w);
 33         else update(x,mid+1,r,rt<<1|1,w);
 34         pushup(rt);
 35     }
 36     int query(int L,int R,int l,int r,int rt)
 37     {
 38         if(L<=l&&r<=R){return ma[rt];}
 39         int mid=(l+r)>>1,ans=0;
 40         if(L<=mid) ans=max(query(L,R,l,mid,rt<<1),ans);
 41         if(R>mid) ans=max(query(L,R,mid+1,r,rt<<1|1),ans);
 42         return ans;
 43     }
 44     #undef il
 45 }seg;
 46 int gint()
 47 {
 48     int ret=0,fh=1;char c=getchar();
 49     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
 50     while(c>='0'&&c<='9'){ret=(ret<<3)+(ret<<1)+c-'0';c=getchar();}
 51     return ret*fh;
 52 }
 53 void get_pr()
 54 {
 55     int cnt=0;
 56     for(int i=2;i<N;i++){
 57         if(!use[i]) pr[++cnt]=i,nxt[i]=i;
 58         for(int j=1;j<=cnt&&i*pr[j]<N;j++){
 59             use[i*pr[j]]=1,nxt[i*pr[j]]=pr[j];
 60             if(i%pr[j]==0) break;
 61         }
 62     }
 63 }
 64 void Div(int x){
 65     num=0;int p;
 66     while(x!=1){
 67         num++;p=son[num]=nxt[x];d[num]=0;
 68         while(x%p==0) x/=p,d[num]++;
 69     }
 70 }
 71 void dfs_ap(int k){
 72     if(k==num+1){
 73         app[++nson]=1;
 74         for(int i=1;i<=num;i++)
 75             app[nson]*=pw[i];
 76         return;}
 77     pw[k]=1;
 78     for(int j=0;j<=d[k];j++)
 79         dfs_ap(k+1),pw[k]*=son[k];
 80 }
 81 void solve(int k)
 82 {
 83     Div(a[k]);nson=0;dfs_ap(1);
 84     for(int i=1;i<=nson;i++)
 85     {
 86         if(!la[app[i]]) la[app[i]]=k;
 87         else{
 88             seg.update(la[app[i]],1,n,1,app[i]);
 89             la[app[i]]=k;
 90         }
 91     }
 92     for(int j=head[k];j;j=edge[j].nxt){
 93         int v=edge[j].to;
 94         Q[v].ans=seg.query(Q[v].l,Q[v].r,1,n,1);
 95     }
 96 }
 97 void init()
 98 {
 99     for(int i=1;i<=n;i++)
100         a[i]=use[N]=head[i]=la[i]=0;
101     for(int i=1;i<=q;i++)
102         Q[i].l=Q[i].r=Q[i].ans=edge[i].to=edge[i].nxt=0;
103     memset(&seg,0,sizeof(seg));
104     cte=0;
105 }
106 int main()
107 {
108     scanf("%d",&T);
109     get_pr();
110     for(int t=1;t<=T;t++)
111     {
112         scanf("%d",&n);
113         for(int i=1;i<=n;i++)
114             a[i]=gint();
115         scanf("%d",&q);
116         for(int i=1;i<=q;i++)
117             Q[i].l=gint(),Q[i].r=gint(),ae(Q[i].l,i);
118         seg.build(1,n,1);
119         for(int i=n;i>=1;i--)
120             solve(i);
121         for(int i=1;i<=q;i++){
122             if(Q[i].l==Q[i].r) Q[i].ans=0;
123             printf("%d\n",Q[i].ans);
124         }init();
125     }
126     return 0;
127 }

转载于:https://www.cnblogs.com/guapisolo/p/9768605.html

HDU 4630 No Pain No Game (线段树+离线)相关推荐

  1. HDU - 4417 Super Mario(主席树/线段树+离线)

    题目链接:点击查看 题目大意:给出由 n 个数的数列,再给出 m 次查询,每次查询需要输出 [ l , r ] 内小于等于 h 的数有多少个 题目分析:大晚上睡不着觉随便做做题,发现这个题目原来可以用 ...

  2. Super Mario HDU - 4417(主席树解决区间数字小于k的个数||线段树+离线)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  3. HDU 4417 Super Mario(线段树离线处理/主席树)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  4. SPOJ - DQUERY D-query(莫队/线段树+离线/主席树)

    题目链接:点击查看 题目大意:给出一个由n个数组成的序列,再给出m次查询,每次查询区间[l,r]中有多少个不同的数 题目分析:莫队模板题,直接套板子就好了 有点意思的是函数返回值为布尔类型,然后没有r ...

  5. No Pain No Game HDU - 4630(gcd+线段树+离线处理)

    Life is a game,and you lose it,so you suicide. But you can not kill yourself before you solve this p ...

  6. HDU 4630 No Pain No Game 树状数组+离线操作

    题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数. ...

  7. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  8. HDU 1394 Minimum Inversion Number(线段树的单点更新)

    点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...

  9. hdu 5493 Queue(逆序对,线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5493 解题思路: 一道线段树的题目,因为是前面或者后面有k个比自己高的人,所以我们应该按照由身高从小到 ...

  10. 【HDU - 4217 】Data Structure? (线段树求第k小数)

    题干: Data structure is one of the basic skills for Computer Science students, which is a particular w ...

最新文章

  1. mysql 什么不能用别名_[转]为何group by后面不能使用别名(除MySQL)
  2. MySQL数据库的高可用方案总结
  3. 对比tensorflow查看打印输出张量Tensor的两种方法(急切执行tf.enable_eager_execution()和tf.Session.run())
  4. [转]白话阿里巴巴Java开发手册高级篇
  5. 使用macOS自带convert,sips命令快速处理图片及转换图片格式
  6. 怎样追求一个你喜欢的人?
  7. java 直播_一对一直播源码开发过程中区分Java和PHP的重要性
  8. 在组件中获取Application
  9. TableCache设置过小造成MyISAM频繁损坏
  10. TCP/IP——链路层简记
  11. CFS之vruntime记录
  12. 【心电信号】基于matlab自适应滤波算法胎儿心电信号提取【含Matlab源码 953期】
  13. HP服务器远程管理工具iLO详细介绍
  14. 照片损坏怎么办,怎么恢复受损照片
  15. ZOJ Problem 1005 jugs
  16. 计算机内存条如何区分频率,怎么看内存条频率,详细教您怎么看内存条频率
  17. 4.5 GPO的编辑
  18. c语言wb是标识符,C语言文件 "w+"与"wb+"区别
  19. 关于github双因素验证问题解决方案
  20. 光脚的快感!仅仅耐克1/8重,一个夏天不会臭脚!徒步不累脚!

热门文章

  1. 分治法( Divide and Conquer)
  2. Spring源码之bean的初始化initializeBean方法解读
  3. RocketMQ之消费者顺序消费源码解析
  4. 容器化之路:谁偷走了我的构建时间
  5. C语言指针及C++引用
  6. centos7安装lamp
  7. Java线程池如何体现自己的用途
  8. 小蚂蚁学习C语言(27)——C语言中的进制转换
  9. Ubuntu安装与配置
  10. 学习MVC3(二)——创建自己的第一个网页:实现用户登陆(1)