zoukankan      html  css  js  c++  java
  • HDU 4630 No Pain No Game (线段树 + 离线)

    题意:给定一个序列,动态的询问你这个序列的某个区间两两最大的最大公约数:

    解题思路:一个区间的最大GCD 就是一个在这个区间出现两次的最大约数。。。。这个题的解题思路是,从后往前扫描,对于A[I]的约数,如果后面出现过,则更新后面那个数的线段树节点。离线的原因主要是因为我们目前的状态,只能解决当前的问题,而且后面的询问,又依赖于现在的状态,所以就要对询问的左区间进行从大到小的排序,然后扫描,如果 i 等于一个询问的左边界,则更新询问。

    解题代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <string>
      6 #include <math.h>
      7 
      8 using namespace std;
      9 
     10 #define maxn 50005
     11 struct op
     12 {
     13   int l , r ;
     14   int num ,mx;
     15 
     16 }ops[maxn];
     17 struct node
     18 {
     19   int l , r, m ;
     20   int num;
     21 }tree[maxn*4];
     22 int L(int c)
     23 {
     24  return 2*c;
     25 }
     26 int R(int c){
     27   return 2*c + 1;
     28 }
     29 void build(int c ,int p , int v )
     30 {
     31     tree[c].l = p;
     32     tree[c].r = v ;
     33     tree[c].m = (p+v)/2;
     34     tree[c].num = 1;
     35     if(p == v)
     36       return ;
     37     build(L(c),p,tree[c].m);
     38     build(R(c),tree[c].m +1,v);
     39 }
     40 void Pushup(int c)
     41 {
     42     tree[c].num =  tree[L(c)].num > tree[R(c)].num ? tree[L(c)].num:tree[R(c)].num;
     43 }
     44 int up[maxn];
     45 void update(int c, int p , int v)
     46 {
     47     if(tree[c].l == tree[c].r && tree[c].l == p)
     48     {
     49        if(tree[c].num < v)
     50           tree[c].num = v;
     51       return ;
     52     }
     53     if(p <= tree[c].m ) update(L(c),p,v);
     54     else update(R(c),p,v);
     55     Pushup(c);
     56 }
     57 int tmax = 0 ;
     58 void getmax(int c, int p , int v)
     59 {
     60     if(p <= tree[c].l && v >= tree[c].r)
     61     {
     62        if(tree[c].num > tmax)
     63         tmax = tree[c].num ;
     64        return ;
     65     }
     66     if(v <= tree[c].m) getmax(L(c),p,v);
     67     else if(p > tree[c].m) getmax(R(c),p,v);
     68     else {
     69       getmax(L(c),p,tree[c].m);
     70       getmax(R(c),tree[c].m+1,v);
     71     }
     72 }
     73 
     74 
     75 bool cmp(struct op  a , struct op b)
     76 {
     77    return a.l > b.l;
     78 }
     79 int hs[100000];
     80 int a[maxn];
     81 int ans[maxn];
     82 int main()
     83 {
     84   //freopen("1010.in","r",stdin);
     85   //freopen("output.txt","w",stdout);
     86   int t;
     87   scanf("%d",&t);
     88   while(t--)
     89   {
     90       memset(hs,0,sizeof(hs));
     91       memset(up,0,sizeof(up));
     92        int n ,m;
     93       scanf("%d",&n);
     94 
     95       build(1,1,n);
     96       for(int i = 1;i <= n;i ++)
     97         scanf("%d",&a[i]);
     98       scanf("%d",&m);
     99       for(int i =1 ;i <= m;i ++)
    100        {
    101          scanf("%d %d",&ops[i].l,&ops[i].r);
    102          ops[i].num = i  ;
    103        }
    104       sort(ops+1,ops+1+m,cmp);
    105 
    106       int k = 1 ;
    107       for(int j = n; j >= 1; j --)
    108       {
    109           int ta = (int)sqrt(a[j]);
    110           for(int i = 1; i<= ta ; i ++ )
    111           {
    112               if(a[j]%i == 0)
    113               {
    114                   int t1 = a[j]/i;
    115                   if(t1 != i)
    116                   {
    117                     if(hs[i] != 0 && i > up[hs[i]])
    118                     {
    119                       update(1,hs[i],i);
    120                       up[hs[i]]  = i ;
    121                     }
    122                     hs[i] = j;
    123                     if(hs[t1] != 0 && t1 > up[hs[t1]])
    124                     {
    125                       update(1,hs[t1],t1);
    126                       up[hs[t1]] = t1;
    127                     }
    128                     hs[t1] = j;
    129                   }
    130                   else{
    131                      if(hs[i] != 0 && i > up[hs[i]])
    132                      {
    133                       update(1,hs[i],i);
    134                       up[hs[i]] = i;
    135                      }
    136                      hs[i] = j;
    137                   }
    138               }
    139           }
    140           while(ops[k].l == j )
    141           {
    142               
    143               tmax = 0 ;
    144               getmax(1,ops[k].l,ops[k].r);
    145               ans[ops[k].num]= tmax;
    146               if(ops[k].l == ops[k].r)
    147                 ans[ops[k].num] = 0 ;
    148               k++;
    149           }
    150         //   printf("%d
    ",tree[1].num);
    151       }
    152       for(int i = 1;i <= m ;i ++)
    153         printf("%d
    ",ans[i]);
    154 
    155   }
    156 
    157   return 0 ;
    158 }
    View Code

    ps。这题卡qsort  好恶心。。。(离线的时候不要对操作进行排序输出了,重开一个数组记录);

    没有梦想,何谈远方
  • 相关阅读:
    20179203李鹏举 《Linux内核原理与分析》第一周学习笔记
    20179223《Linux内核原理与分析》第八周学习笔记
    20179223《Linux内核原理与分析》第七周学习笔记
    20179223《Linux内核原理与解析》第六周学习笔记
    20179223《Linux内核原理与分析》第五周学习笔记
    20179223《Linux内核原理与分析》第三周学习笔记
    20179223《Linux内核原理与分析》第二周学习笔记
    20179223《Linux内核原理与分析》第一周学习笔记
    51nod贪心算法入门-----活动安排问题2
    51nod贪心算法入门-----活动安排问题
  • 原文地址:https://www.cnblogs.com/zyue/p/3245841.html
Copyright © 2011-2022 走看看