zoukankan      html  css  js  c++  java
  • Coprime Sequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

    Total Submission(s): 217    Accepted Submission(s): 126

    Problem Description

    Do you know what is called ``Coprime Sequence''? That is a sequence consists of n positive integers, and the GCD (Greatest Common Divisor) of them is equal to 1.
    ``Coprime Sequence'' is easy to find because of its restriction. But we can try to maximize the GCD of these integers by removing exactly one integer. Now given a sequence, please maximize the GCD of its elements.

     

    Input

    The first line of the input contains an integer T(1T10), denoting the number of test cases.
    In each test case, there is an integer n(3n100000) in the first line, denoting the number of integers in the sequence.
    Then the following line consists of n integers a1,a2,...,an(1ai109), denoting the elements in the sequence.

     

    Output

    For each test case, print a single line containing a single integer, denoting the maximum GCD.

     

    Sample Input

     

    3
    3
    1 1 1
    5
    2 2 2 3 2
    4
    1 2 4 8

    Sample Output

    1

    2

    2

    //T 组数据,n 个数,开始时,n 个数 gcd 为 1 ,现可以任意抽走一个数,问剩下数最大 gcd 是多少?

    // st 表很好做,O(n*logn) + n * O(n) 的时间

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 #define MX 100005
     6 
     7 int n,m;
     8 int dp[MX][20];
     9 int mi[MX];
    10 int data[MX];
    11 
    12 int gcd(int a,int b)
    13 {return b==0?a:gcd(b,a%b);}
    14 
    15 void build()
    16 {
    17     mi[0]=-1;
    18     for (int i=1;i<=n;i++)
    19     {
    20         mi[i]=((i&(i-1))==0) ? mi[i-1]+1:mi[i-1];   //注意位运算优先级很低
    21         dp[i][0]=data[i];
    22     }
    23     for (int k=1;k<=mi[n];k++)
    24     {
    25         for (int i=1; (i+(1<<k)-1)<=n ;i++)
    26         {
    27             dp[i][k]=gcd(dp[i][k-1],dp[i+(1<<(k-1))][k-1]);
    28         }
    29     }
    30 }
    31 
    32 int find_(int a,int b)
    33 {
    34     int x = mi[b-a+1];
    35     return gcd(dp[a][x],dp[b-(1<<x)+1][x]);
    36 }
    37 
    38 int main()
    39 {
    40     int T;
    41     cin>>T;
    42     while (T--)
    43     {
    44         scanf("%d",&n);
    45         for (int i=1;i<=n;i++)
    46             scanf("%d",&data[i]);
    47         build();
    48         int ans = 1;
    49         for (int i=1;i<=n;i++)
    50         {
    51             int res;
    52             if (i==1)
    53                 res = find_(2,n);
    54             else if (i==n)
    55                 res = find_(1,n-1);
    56             else
    57                 res = gcd(find_(1,i-1),find_(i+1,n));
    58             ans = max(ans,res);
    59         }
    60         printf("%d
    ",ans);
    61     }
    62 }
    View Code

     强行上log n 啊,啊哈哈,其实,只要从左向右扫一遍,存储gcd前缀和,再从右向左扫一遍,存gcd后缀和,然后枚举要剔除的数即可

  • 相关阅读:
    IIS7.5应用程序池集成模式和经典模式的区别介绍(转)
    (转)Extjs4 展示图片与图片的更新
    webservices发布后远程无法调试的解决方法
    .Net通过OleDb方式读取Excel
    1000个JQuery插件(转载)
    2006年中科大计算机考研复试机试题
    2. 最好使用C++转型操作符
    16. 谨记8020法则
    英语阅读理解中表示作者态度的词汇汇总
    5. 对定制的“类型转换函数”保持警觉
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6826988.html
Copyright © 2011-2022 走看看