• CF 474/F, 线段树 + 一点数学


    啊回家真是颓,一周了什么都没做

    题目大意:给出一坨数,每次询问区间当中有多少个数能把其他区间内的所有数整除

    解:由于我是知道这个是线段树专题,所以一开始就奔着gcd去了,想了一下还真是gcd,因为如果一个数a能整除另一个数b,那么gcd(a,b)一定为a,所以这说明可以做区间加法,直接上线段树就是,询问个数的时候还傻叉地想了一会,后面发现给每个线段记一下当前线段表示的gcd有几个就行,合并直接合并(可以证明现在这个线段的gcd一定是作为最优的取值,因为没有数等于这个gcd说明没有数能整除当前区间,那么合并上去也不会导致少解)

     1 #include <cstdio>
     2 #include <string>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstring>
     7 #include <complex>
     8 #include <set>
     9 #include <vector>
    10 #include <map>
    11 #include <queue>
    12 #include <deque>
    13 #include <ctime>
    14 
    15 using namespace std;
    16 
    17 const double EPS = 1e-8;
    18 
    19 #define ABS(x) ((x)<0?(-(x)):(x))
    20 #define SQR(x) ((x)*(x))
    21 #define MIN(a,b) ((a)<(b)?(a):(b))
    22 #define MAX(a,b) ((a)>(b)?(a):(b))
    23 
    24 #define LSON(x) ((x)<<1)
    25 #define RSON(x) (((x)<<1)+1)
    26 #define LOWBIT(x) ((x)&(-(x)))
    27 #define MAXS 1111
    28 #define MAXN 222222
    29 #define VOIDPOINT 0
    30 #define LL long long
    31 #define OO 214748364
    32 
    33 
    34 struct segTree{
    35     int gcd[MAXN*4], num[MAXN*4], l[MAXN*4], r[MAXN*4], mid[MAXN*4];
    36     int gx, gy, gz;
    37     inline void updata(const int &kok) {
    38         gcd[kok] = __gcd(gcd[LSON(kok)], gcd[RSON(kok)]);
    39         num[kok] = (gcd[kok] == gcd[LSON(kok)] ? num[LSON(kok)] : 0) + (gcd[kok] == gcd[RSON(kok)] ? num[RSON(kok)] : 0);        
    40     }
    41     void build(int kok, int ll, int rr, int *a) {
    42         l[kok] = ll; r[kok] = rr;
    43         if (ll == rr) {
    44             gcd[kok] = a[ll]; num[kok] = 1;
    45             return ;
    46         }
    47         int m = mid[kok] = (ll + rr) >> 1;
    48         build(LSON(kok), ll, m, a); build(RSON(kok), m+1, rr, a);
    49         updata(kok);
    50     }
    51     int getGCD(int kok) {
    52         if (gx <= l[kok] && r[kok] <= gy) {
    53             return gcd[kok];
    54         }
    55         if (gy <= mid[kok]) 
    56             return getGCD(LSON(kok));
    57         else if (gx > mid[kok]) 
    58             return getGCD(RSON(kok));
    59         else
    60             return __gcd(getGCD(LSON(kok)), getGCD(RSON(kok)));
    61     }
    62     int query(int kok) const {
    63         if (gx <= l[kok] && r[kok] <= gy) {
    64             return gz == gcd[kok] ? num[kok] : 0;
    65         }
    66         if (gy <= mid[kok]) 
    67             return query(LSON(kok));
    68         else if (gx > mid[kok]) 
    69             return query(RSON(kok));
    70         else
    71             return (query(LSON(kok)) + query(RSON(kok)));
    72 
    73     }
    74     void set(int a = 0, int b = 0, int c = 0) {
    75         gx = a; gy = b; gz = c;
    76     }
    77 } Tree;
    78 
    79 int n, a[MAXN];
    80 
    81 int main() {
    82 //    freopen("test.txt", "r", stdin);
    83     scanf("%d", &n);
    84     for (int i = 0; i < n; ++i) {
    85         scanf("%d", a+i+1);
    86     }
    87     Tree.build(1, 1, n, a);
    88     int m, l, r, t;
    89     scanf("%d", &m);
    90     while (m--) {
    91         scanf("%d%d", &l, &r);
    92         Tree.set(l, r);
    93         t = Tree.getGCD(1);
    94         Tree.set(l, r, t);
    95         printf("%d
    ", r - l - Tree.query(1) + 1);
    96     }
    97     return 0;
    98 }
    CF474F
  • 相关阅读:
    20200323 Go语言基础
    20200313 图表工具与redis使用
    20200312 CMDB的磁盘数据查询
    20200311 CMDB的表设计
    20200320 代码发布之完结
    20200319 代码发布之任务发布钩子脚本
    Ubuntu 安装 MySQL 服务
    使用U盘重装系统(删除掉系统自带的Windows 10)
    Linux & Windows 上安装 Qt
    初次使用Tampermonkey脚本管理器
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/5672814.html
Copyright © 2020-2023  润新知