• HDU 5869 Different GCD Subarray Query 离线+树状数组


    Different GCD Subarray Query



    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
     

    题意

      长度n的序列, m个询问区间[L, R], 问区间内的所有子段的不同GCD值有多少种.

    题解:

      固定右端点

      预处理出 每个点向左延伸 的 不同gcd值

      这样的 值不会超过log a 个

      然后问题就变成了 问你一段区间内不同 gcd 值有多少,值是很少的 (询问一个区间有多少颜色的题型)

      树状数组维护就可以了

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    
    typedef long long LL;
    const long long INF = 1e18;
    const double Pi = acos(-1.0);
    const int N = 1e6+10, M = 1e2+11, mod = 1e9+7, inf = 2e9;
    
    int n,q,a[N],ans[N];
    int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b);}
    vector<pii> G[N];
    struct QQ{
            int l,r,id;
            bool operator < (const QQ &a) const {
                 return a.r > r;
            }
    }Q[N];
    int C[N],vis[N];
    void update(int x,int c) {
            for(int i =x; i < N; i+=i&(-i)) C[i] += c;
    }
    int ask(int x) {
            int s =0 ;
            for(int i = x; i; i-= i & (-i))s += C[i];
            return s;
    }
    int main() {
            while(scanf("%d%d",&n,&q)!=EOF) {
                for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
                for(int i = 0; i <= n; ++i) G[i].clear();
                for(int i = 1; i <= n; ++i) {
                        int x = a[i];
                        int y = i;
                        for(int j = 0; j < G[i-1].size(); ++j) {
                            int res = gcd(x,G[i-1][j].first);
                            if(x != res) {
                                    G[i].push_back(MP(x,y));
                                    x = res;
                                    y = G[i-1][j].second;
                            }
                        }
                        G[i].push_back(MP(x,y));
                }
                memset(C,0,sizeof(C));
                memset(vis,0,sizeof(vis));
                for(int i = 1; i <= q; ++i) {scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].id = i;}
                sort(Q+1,Q+q+1);
                for(int R = 0, i = 1; i <= q; ++i) {
                        while(R < Q[i].r) {
                            R++;
                            for(int j = 0; j < G[R].size(); ++j) {
                                int res = G[R][j].first;
                                int ids = G[R][j].second;
                                if(vis[res]) update(vis[res],-1);
                                vis[res] = ids;
                                update(vis[res],1);
                            }
                        }
                        ans[Q[i].id] = ask(R) - ask(Q[i].l-1);
                }
                for(int i = 1; i <= q; ++i) cout<<ans[i]<<endl;
            }
            return 0;
    }
  • 相关阅读:
    MarkDown的快速入门
    openCV打开摄像头,用openGL实现纹理贴图和视频预览
    tensorflow中的dropout是怎么实现的?
    BEEPS-仿美图秀秀磨皮算法,让美女的皮肤更光滑
    鄙人提出的PBDRLSE分割算法(绝对原创)
    怀旧风格照片特效
    铅笔特效算法
    背光图像的增强
    关于push和concat的性能问题
    小程序日历签到
  • 原文地址:https://www.cnblogs.com/zxhl/p/5865948.html
Copyright © 2020-2023  润新知