CCF 201709-5 除法(线段树)

Posted qaqorz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF 201709-5 除法(线段树)相关的知识,希望对你有一定的参考价值。

操作1:给[l, r]中v的倍数除v

操作2:查询[l, r]的和

思路:类似势能线段树(例题:HDU4027)的思想,首先忽略v=1的操作,然后,1e6数据范围内的数就算每次都除以2,也不用太多次就能变为1,而变为1之后就不用再处理了,所以遍历区间[l, r]找到需要修改的数进行单点修改就行了

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #define LL long long
 6 #define debug(x) cout << "[" << x << "]" << endl
 7 #define lid id << 1
 8 #define rid id << 1 | 1
 9 using namespace std;
10 
11 const int mx = 1e5+5;
12 struct tree{
13     int l, r;
14     LL sum;
15 }tree[mx<<2];
16 int a[mx];
17 
18 void push_up(int id){
19     tree[id].sum = tree[lid].sum + tree[rid].sum;
20 }
21 
22 void build(int l, int r, int id){
23     tree[id].l = l;
24     tree[id].r = r;
25     if (l == r){
26         tree[id].sum = a[l];
27         return;
28     }
29     int mid = (l+r)>>1;
30     build(l, mid, lid);
31     build(mid+1, r, rid);
32     push_up(id);
33 }
34 
35 void upd(int x, int id, int c){
36     if (tree[id].l == tree[id].r){
37         tree[id].sum = c;
38         return;
39     }
40     int mid = (tree[id].l + tree[id].r)>>1;
41     if (x <= mid) upd(x, lid, c);
42     else upd(x, rid, c);
43     push_up(id);
44 }
45 
46 LL query(int l, int r, int id){
47     if (tree[id].l == l && tree[id].r == r) return tree[id].sum;
48     int mid = (tree[id].l + tree[id].r) >> 1;
49     if (mid >= r) return query(l, r, lid);
50     else if (mid < l) return query(l, r, rid);
51     return query(l, mid, lid) + query(mid+1, r, rid);
52 }
53 
54 int main(){
55     int n, q;
56     scanf("%d%d", &n, &q);
57     for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
58     build(1, n, 1);
59     while (q--){
60         int op, l, r, c;
61         scanf("%d%d%d", &op, &l, &r);
62         if (op == 1){
63             scanf("%d", &c);
64             if (c == 1) continue;
65             for (int i = l; i <= r; i++){
66                 if (a[i] >= c && a[i]%c == 0){
67                     a[i] /= c;
68                     upd(i, 1, a[i]);
69                 }
70             }
71         }
72         else printf("%lld
", query(l, r, 1));
73     }
74     return 0;
75 }

 

以上是关于CCF 201709-5 除法(线段树)的主要内容,如果未能解决你的问题,请参考以下文章

CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)

CCF201912-5 魔数线段树(100分题解链接)

线段树维护区间开方/除法

CCF201609-5 祭坛线段树(100分解题链接)

CCF202012-5 星际旅行线段树(100分题解链接)

线段树详解