• HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869

    问你l~r之间的连续序列的gcd种类。

    首先固定右端点,预处理gcd不同尽量靠右的位置(此时gcd种类不超过loga[i]种)。

    预处理gcd如下代码,感觉真的有点巧妙...

     1         for(int i = 1; i <= n; ++i) {
     2             int x = a[i], y = i;
     3             for(int j = 0; j < ans[i - 1].size(); ++j) {
     4                 int gcd = GCD(x, ans[i - 1][j].first);
     5                 if(gcd != x) {
     6                     ans[i].push_back(make_pair(x, y));
     7                     x = gcd, y = ans[i - 1][j].second;
     8                 }
     9             }
    10             ans[i].push_back(make_pair(x, y));
    11         }

    然后用树状数组维护右端点固定的gcd位置。

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 1e6 + 5;
    17 int a[N/10 + 5], bit[N], _pos[N]; //_pos存的是gcd上一次出现的位置
    18 vector <P> ans[N/10 + 5]; //存的是以i为右端点的gcd
    19 struct query {
    20     int l, r, pos;
    21     bool operator <(const query& cmp) const {
    22         return r < cmp.r;
    23     }
    24 }q[N/10 + 5];
    25 int res[N/10 + 5]; //答案
    26 
    27 void init(int n) {
    28     memset(_pos, 0, sizeof(_pos));
    29     memset(bit, 0, sizeof(bit));
    30     for(int i = 1; i <= n; ++i) {
    31         ans[i].clear();
    32     }
    33 }
    34 
    35 int GCD(int a, int b) {
    36     return b ? GCD(b, a % b): a;
    37 }
    38 
    39 void add(int i, int x) {
    40     for( ; i <= N; i += (i&-i))
    41         bit[i] += x;
    42 }
    43 
    44 int sum(int i) {
    45     int s = 0;
    46     for( ; i >= 1; i -= (i&-i))
    47         s += bit[i];
    48     return s;
    49 }
    50 
    51 int main()
    52 {
    53     int n, m;
    54     while(scanf("%d %d", &n, &m) != EOF) {
    55         init(n);
    56         for(int i = 1; i <= n; ++i) {
    57             scanf("%d", a + i);
    58         }
    59         for(int i = 1; i <= m; ++i) {
    60             scanf("%d %d", &q[i].l, &q[i].r);
    61             q[i].pos = i;
    62         }
    63         for(int i = 1; i <= n; ++i) {
    64             int x = a[i], y = i;
    65             for(int j = 0; j < ans[i - 1].size(); ++j) {
    66                 int gcd = GCD(x, ans[i - 1][j].first);
    67                 if(gcd != x) {
    68                     ans[i].push_back(make_pair(x, y));
    69                     x = gcd, y = ans[i - 1][j].second;
    70                 }
    71             }
    72             ans[i].push_back(make_pair(x, y));
    73         }
    74         sort(q + 1, q + m + 1);
    75         int p = 1;
    76         for(int i = 1; i <= n; ++i) {
    77             for(int j = 0; j < ans[i].size(); ++j) {
    78                 if(!_pos[ans[i][j].first]) {
    79                     add(ans[i][j].second, 1);
    80                     _pos[ans[i][j].first] = ans[i][j].second;
    81                 } else {
    82                     add(_pos[ans[i][j].first], -1);
    83                     _pos[ans[i][j].first] = ans[i][j].second;
    84                     add(ans[i][j].second, 1);
    85                 }
    86             }
    87             while(i == q[p].r && p <= m) {
    88                 res[q[p].pos] = sum(q[p].r) - sum(q[p].l - 1);
    89                 ++p;
    90             }
    91         }
    92         for(int i = 1; i <= m; ++i) {
    93             printf("%d
    ", res[i]);
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    【数据结构】并查集
    项目管理【12】 | 项目范围管理-收集需求
    项目管理【11】 | 项目范围管理-规划范围管理
    项目管理【10】 | 项目范围管理-范围管理概述
    Visual Studio代码远程调试方法
    项目管理【09】 | 项目整体管理-结束项目或阶段
    操作系统【2】Linux系统安装
    操作系统【1】Linux基础知识
    移动端开发案例【2】头部组件开发
    移动端开发案例【1】全局样式配置
  • 原文地址:https://www.cnblogs.com/Recoder/p/5866836.html
Copyright © 2020-2023  润新知