zoukankan      html  css  js  c++  java
  • GCD (hdu 5726)

    GCD

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1497    Accepted Submission(s): 483


    Problem Description
    Give you a sequence of N(N100,000) integers : a1,...,an(0<ai1000,000,000). There are Q(Q100,000) queries. For each query l,r you have to calculate gcd(al,,al+1,...,ar) and count the number of pairs(l,r)(1l<rN)such that gcd(al,al+1,...,ar) equal gcd(al,al+1,...,ar).
     
    Input
    The first line of input contains a number T, which stands for the number of test cases you need to solve.

    The first line of each case contains a number N, denoting the number of integers.

    The second line contains N integers, a1,...,an(0<ai1000,000,000).

    The third line contains a number Q, denoting the number of queries.

    For the next Q lines, i-th line contains two number , stand for the li,ri, stand for the i-th queries.
     
    Output
    For each case, you need to output “Case #:t” at the beginning.(with quotes, t means the number of the test case, begin from 1).

    For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs(l,r) such that gcd(al,al+1,...,ar) equal gcd(al,al+1,...,ar).
     
    Sample Input
    1 5 1 2 4 6 7 4 1 5 2 4 3 4 4 4
     
    Sample Output
    Case #1: 1 8 2 4 2 4 6 1
     
    Author
    HIT
     
    Source
    思路:RMQ+二分
    一开始我用的线段树去维护各个区间的gcd但是超时,并且我没有优化。
    暴力统计的各个区间的gcd;
    后来发现gcd的性质,也就是求数的gcd,这些数的个数越多那么gcd越小,所以从左到右,以某个端点开始的gcd的大小随着区间增大而减小,那么二分统计以某个点为端点的gcd
    最多每个端点二分30次。
    然后还是超时。
    然后改用RMQ基于稀疏表的,查询O(n);
    复杂度(n*log(n));
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<string.h>
     5 #include<stdlib.h>
     6 #include<queue>
     7 #include<map>
     8 #include<math.h>
     9 using namespace std;
    10 typedef long long LL;
    11 int RMQ[20][100005];
    12 int ans[100005];
    13 map<int,LL>my;
    14 int gcd(int n,int m)
    15 {
    16         if(m==0)
    17                 return n;
    18         else  if(n%m==0)
    19         {
    20                 return m;
    21         }
    22         else return gcd(m,n%m);
    23 }
    24 int main(void)
    25 {
    26         int i,j,k;
    27         int n,m;
    28         scanf("%d",&k);
    29         int ca=0;
    30         while(k--)
    31         {
    32                 my.clear();
    33                 scanf("%d",&n);
    34                 for(i=1; i<=n; i++)
    35                 {
    36                         scanf("%d",&ans[i]);
    37                 }
    38                 for(i=1; i<=n; i++)
    39                 {
    40                         RMQ[0][i]=ans[i];
    41                 }
    42                 scanf("%d",&m);
    43                 for(i=1; i<20; i++)
    44                 {
    45                         for(j=1; j<=n; j++)
    46                         {
    47                                 if(j+(1<<i)-1<=n)
    48                                 {
    49                                         RMQ[i][j]=gcd(RMQ[i-1][j],RMQ[i-1][j+(1<<(i-1))]);
    50                                 }
    51                         }
    52                 }
    53                 for(i=1; i<=n; i++)
    54                 {
    55                         for(j=i; j<=n;)
    56                         {
    57                                 int t=log2(j-i+1);
    58                                 int ac=gcd(RMQ[t][i],RMQ[t][j-(1<<t)+1]);
    59                                 int l=j;
    60                                 int r=n;
    61                                 int id=0;
    62                                 while(l<=r)
    63                                 {
    64                                         int mid=(l+r)/2;
    65                                         int c=log2(mid-i+1);
    66                                         int ak=gcd(RMQ[c][i],RMQ[c][mid-(1<<c)+1]);
    67                                         if(ak>=ac)
    68                                         {
    69                                                 id=mid;
    70                                                 l=mid+1;
    71                                         }
    72                                         else r=mid-1;
    73                                 }
    74                                 my[ac]+=id-j+1;
    75                                 j=id+1;
    76                         }
    77                 }
    78                 printf("Case #%d:
    ",++ca);
    79                 while(m--)
    80                 {
    81                         int x,y;
    82                         scanf("%d %d",&x,&y);
    83                         if(x>y)
    84                         {
    85                             swap(x,y);
    86                         }
    87                         int ct=log2(y-x+1);
    88                         int acc=gcd(RMQ[ct][x],RMQ[ct][y-(1<<ct)+1]);
    89                         printf("%d %lld
    ",acc,my[acc]);
    90                 }
    91         }
    92         return 0;
    93 }
    油!油!you@
  • 相关阅读:
    微信客服系统开发SDK使用教程-给好友发消息任务
    微信客服系统开发SDK使用教程-客户端选择微信号登陆/登出通知
    微信客服系统开发SDK使用教程-客户端退出通知
    php优秀框架codeigniter学习系列——CI_Security类学习
    php优秀框架codeigniter学习系列——CI_Output类的学习
    php优秀框架codeigniter学习系列——CI_Router类学习
    My IELTS result has come out 我的雅思成绩出来了
    Travel notes in Vietnam
    asp.net学习
    makefile简单学习
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5689884.html
Copyright © 2011-2022 走看看