• hdu 5869 Different GCD Subarray Query BIT+GCD 2016ICPC 大连网络赛


    Different GCD Subarray Query

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 828    Accepted Submission(s): 300


    Problem Description
    This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it looks, Bob cannot figure it out himself. Now he turns to you for help, and here is the problem:
      
      Given an array a of N positive integers a1,a2,aN1,aN; a subarray of a is defined as a continuous interval between a1 and aN. In other words, ai,ai+1,,aj1,aj is a subarray of a, for 1ijN. For a query in the form (L,R), tell the number of different GCDs contributed by all subarrays of the interval [L,R].
      
     
    Input
    There are several tests, process till the end of input.
      
      For each test, the first line consists of two integers N and Q, denoting the length of the array and the number of queries, respectively. N positive integers are listed in the second line, followed by Q lines each containing two integers L,R for a query.

    You can assume that 
      
        1N,Q100000 
        
       1ai1000000
     
    Output
    For each query, output the answer in one line.
     
    Sample Input
    5 3 1 3 4 6 9 3 5 2 5 1 5
     
    Sample Output
    6 6 6
     
    Source

     题意:有n个数字依次存放在一个数组中(n<=1e5),每个数字<=1e6,数组中每个子序列可以产生一个整个子序列的最大公约数,有q个询问(q<=1e5),每次询问包括两个数字,l,r询问下标从l,到r的区间内一共有多少个不同的GCD;

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <bitset>
    #include <set>
    #define MM(a,b) memset(a,b,sizeof(a));
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    #define CT continue
    #define SC scanf
    const int N=1e5+10;
    int n,qur,a[N],tree[N],ans[N],pos[10*N];
    
    struct node{
       int l,id;
    };
    
    int gcd(int a,int b)
    {
       if(b==0) return a;
       else return gcd(b,a%b);
    }
    
    int lowbit(int i)
    {
       return i&(-i);
    }
    
    int add(int pos,int val)
    {
        while(pos<=n){
            tree[pos]+=val;
            pos+=lowbit(pos);
        }
    }
    
    int query(int r)
    {
        int s=0;
        while(r>=1){
            s+=tree[r];
            r-=lowbit(r);
        }
        return s;
    }
    
    vector<node> q[N],lgcd[N];
    
    void solve()
    {
        for(int i=1;i<=n;i++){
            if(pos[a[i]]!=-1) add(pos[a[i]],-1);
            pos[a[i]]=i;
            add(i,1);
            int val=a[i];
            for(int j=i-1;j>=1;j--){
               int k=gcd(val,a[j]);
               if(pos[k]<j){
                  if(pos[k]!=-1) add(pos[k],-1);
                  pos[k]=j;
                  add(j,1);
               }
               if(k==1) break;
               val=k;
            }
            for(int j=0;j<q[i].size();j++){
                int l=q[i][j].l,id=q[i][j].id;
                ans[id]=query(i)-query(l-1);
            }
        }
    }
    
    int main()
    {
        while(~SC("%d%d",&n,&qur)){
           MM(tree,0);
           MM(pos,-1);
           for(int i=1;i<=n;i++) {
              SC("%d",&a[i]);
              q[i].clear();
           }
           for(int i=1;i<=qur;i++) {
               int l,r;
               SC("%d%d",&l,&r);
               q[r].push_back((node){l,i});
           }
           solve();
           for(int i=1;i<=qur;i++) printf("%d
    ",ans[i]);
        }
        return 0;
    }
    

      分析:

    错因分析:比赛的时候想到了每个数字的gcd并不会很多,,但是想到的解决方法是,先统计出从1到i(1<=i<=n)的各个位置所拥有的gcd种类数,,然后对于一个区间[l,r],用种类数r-种类数l-1,,,,但是这样有个很显然的错误就是[l,l-1]内出现的gcd有可能在[l,r]内再次出现,所以这样肯定就错了

    纠正与解答:对于这样的问题,

    1.我们可以从1-n依次固定右端点,然后从i向前扫,得到一个gcd,然后用BIT维护其gcd最靠右位置,在BIT中+1(可以想象,固定右端点后,越靠右,则不管怎样的区间,都尽可能包含)

    2.最多在loga时间内gcd衰减至1.复杂度nlogn*logn;

  • 相关阅读:
    Tomcat和nginx负载均衡算法
    (转)CSS浮动(float,clear)通俗讲解
    MvcSiteMapProvider配置使用
    idea出现jdk版本过低导致无法通过编译
    java生成自己的doc文档
    RabbitMQ的应用场景
    java 变量和常量
    IDEA创建新空项目
    java中整型、浮点型、char型扩展
    java中数据类型占多少字节
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5869893.html
Copyright © 2020-2023  润新知