zoukankan      html  css  js  c++  java
  • 【NOIP模拟】数字对(RMQ,二分)

    题意:小H是个善于思考的学生,现在她又在思考一个有关序列的问题。 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。

    这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R – L。

    小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。

    100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.

    思路:

     1 #include<map>
     2 #include<set>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<cstring>
     7 #include<cstdlib>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define MAXN 510000
    11 using namespace std;
    12 
    13 
    14 int f[MAXN][20],g[MAXN][20];
    15 int a[MAXN],b[MAXN],c[MAXN];
    16 int n,num;
    17 
    18 int gcd(int x,int y)
    19 {
    20     int a,b,r,t;
    21     a=x; b=y;
    22     if(a<b){t=a;a=b;b=t;}
    23     while(1)
    24     {
    25         r=a%b;
    26         a=b;
    27         b=r;
    28         if(!r) break;
    29         
    30     }
    31     return a;
    32 } 
    33 
    34 int query1(int x,int y)
    35 {
    36   int len,l;
    37   len=y-x+1; l=log(len)/log(2);
    38   return gcd(f[x][l],f[y-(1<<l)+1][l]);
    39 }
    40 
    41 int query2(int x,int y)
    42 {
    43   int len,l;
    44   len=y-x+1; l=log(len)/log(2);
    45   return min(g[x][l],g[y-(1<<l)+1][l]);
    46 }
    47 int isok(int k)
    48 {
    49     num=0;
    50     for(int i=1;i+k-1<=n;i++)
    51     {
    52         int s1=query1(i,i+k-1);
    53         int s2=query2(i,i+k-1);
    54         if(s1==s2) b[++num]=i;
    55     //    printf("%d %d %d %d
    ",i,i+k-1,s1,s2);
    56     }
    57     if(num) return 1;
    58      else return 0;
    59 }
    60 int main()
    61 {
    62     freopen("1.in","r",stdin);
    63     freopen("1.out","w",stdout);
    64     scanf("%d",&n);
    65     for(int i=1;i<=n;i++) 
    66     {
    67         scanf("%d",&a[i]);
    68         f[i][0]=g[i][0]=a[i];
    69     }
    70     int len=log(n)/log(2);
    71     for(int i=1;i<=len;i++) 
    72      for(int j=1;j+(1<<i)-1<=n;j++) 
    73      {
    74          f[j][i]=gcd(f[j][i-1],f[j+(1<<(i-1))][i-1]);
    75          g[j][i]=min(g[j][i-1],g[j+(1<<(i-1))][i-1]);
    76      }
    77     int l,r,mid,last,ans;
    78     l=1;r=n;last=ans=1;c[1]=1;
    79     while(l<=r)
    80     {
    81         int mid=(l+r)/2;
    82         if(isok(mid))
    83         {
    84             last=mid; ans=num;
    85             for(int i=1;i<=num;i++) c[i]=b[i];
    86             l=mid+1;
    87         }
    88          else r=mid-1;
    89     }
    90     printf("%d %d
    ",ans,last-1);
    91     for(int i=1;i<=ans-1;i++) printf("%d ",c[i]);    
    92     printf("%d",c[ans]);
    93 }
  • 相关阅读:
    发呆发呆发呆发呆发呆发呆发
    大众捷达看想吃 v 觉得分开才相聚离开都出现
    yjggj
    test4
    test3
    test2
    test1
    Java并发之线程池ThreadPoolExecutor源码分析学习
    Java并发之AQS同步器学习
    ThreadLocal和ThreadLocalMap源码分析
  • 原文地址:https://www.cnblogs.com/myx12345/p/9270009.html
Copyright © 2011-2022 走看看