Codefroces 920F SUM and REPLACE(线段树)

SUM and REPLACE

题意:给你n个数,进行m次操作,分别是将区间[l,r]内的所有数替换成自己的因子数 和 对区间[l,r]进行求和。

题解:可以发现2的因子个数还是2,1的因子个数还是1,所以如果某个数被更新成1或者2之后就不需要再进行更新了。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 using namespace std;
 6 const int N = 3e5+5;
 7 const int M = 1e6+5;
 8 ll tree[N<<2];
 9 bool ok[N<<2];
10 int num[M], a[N];
11 int n, m;
12 void PushUp(int rt)
13 {
14     tree[rt] = tree[rt<<1] + tree[rt<<1|1];
15     ok[rt] = ok[rt<<1] && ok[rt<<1|1];
16 }
17 void Build(int l, int r, int rt)
18 {
19     if(l == r)
20     {
21         tree[rt] = a[l];
22         if(tree[rt] == 1 || tree[rt] == 2) ok[rt] = 1;
23         else ok[rt] = 0;
24         return ;
25     }
26     int m = l+r >> 1;
27     Build(lson);
28     Build(rson);
29     PushUp(rt);
30 }
31 ll Query(int L, int R, int l, int r, int rt)
32 {
33     if(L <= l && r <= R)
34         return tree[rt];
35     int m = l+r >> 1;
36     ll ans = 0;
37     if(L <= m) ans += Query(L,R,lson);
38     if(m < R)  ans += Query(L,R,rson);
39     return ans;
40 }
41
42 void Revise(int L, int R, int l, int r, int rt)
43 {
44     if(ok[rt]) return ;
45     if(l == r)
46     {
47         tree[rt] = num[tree[rt]];
48         if(tree[rt] == 1 || tree[rt] == 2) ok[rt] = 1;
49         return ;
50     }
51     int m = l+r >> 1;
52     if(L <= m) Revise(L,R,lson);
53     if(m < R) Revise(L,R,rson);
54     PushUp(rt);
55 }
56 int main()
57 {
58     ios::sync_with_stdio(false);
59     cin.tie(0);
60     cout.tie(0);
61     memset(num, 0, sizeof(num));
62     for(int i = 1; i < M; i++)
63         for(int j = i; j < M; j+=i)
64                 num[j]++;
65     cin >> n >> m;
66     for(int i = 1; i <= n; i++)
67         cin >> a[i];
68     Build(1,n,1);
69     int q, l, r;
70     while(m--)
71     {
72         cin >> q >> l >> r;
73         if(q == 2)
74             cout << Query(l,r,1,n,1) << endl;
75         else
76             Revise(l,r,1,n,1);
77     }
78     return 0;
79 }

原文地址:https://www.cnblogs.com/MingSD/p/8412621.html

时间: 2024-08-30 17:32:41

Codefroces 920F SUM and REPLACE(线段树)的相关文章

codeforces CF920F SUM and REPLACE 线段树 线性筛约数

$ \Rightarrow $ 戳我进CF原题 F. SUM and REPLACE time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input output: standard output Let $ D(x) $ be the number of positive divisors of a positive integer $ x $ . For example, $

【Educational Codeforces Round 37】F. SUM and REPLACE 线段树+线性筛

题意 给定序列$a_n$,每次将$[L,R]$区间内的数$a_i$替换为$d(a_i)$,或者询问区间和 这题和区间开方有相同的操作 对于$a_i \in (1,10^6)$,$10$次$d(a_i)$以内肯定可以最终化为$1$或者$2$,所以线段树记录区间最大值和区间和,$Max\le2$就返回,单点暴力更新,最后线性筛预处理出$d$ 时间复杂度$O(m\log n)$ 代码 #include <bits/stdc++.h> using namespace std; typedef long

CodeForces - 920F SUM and REPLACE (线段树)

题意:给N个数M次操作,(1<=N,M<=3e5, 1<=ai<=1e6),1是使[L,R]中的每个元素变成其因子的个数之和:2是求[L,R]区间之和 分析:看上去就很线段树的一题,但是却思考了很久.发现1和2即使对其,也不会改变二者的值.而且一个大于2的数进行多次1操作,也最终会退化到2. 先预处理筛出1e6以内各数的质因子个数和.在线段树的节点中维护两个值:区间和以及区间最大值.在update函数中,如果该区间的最大值不超过2,那么该区间没有更新的必要:若超过2,则递归向下找到

Codeforces 85D Sum of Medians(线段树)

85D Sum of Medians 题目链接 题意:一个集合有添加,删除元素,每次查询输出集合位置为i % 5 == 3的位置和 思路:线段树,线段树记录下% 5 == 0, 1, 2, 3, 4的和,并且记录一个mov表示右移多少,每次添加一个值的时候,就当前位置之后的一整段位置都要右移一个单位,这样去搞线段树维护一下即可 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <

Codeforces 920F. SUM and REPLACE

题目大意: 一个数列 支持两种操作 1 把区间内的数变成他们自己的约数个数 2 求区间和 思路: 可以想到每个数最终都会变成2或1 然后我们可以线段树 修改的时候记录一下每段有没有全被修改成1或2 是的话就不修改了 不是就暴力修改 因为每个数被修改的次数很小 1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring&g

Educational Codeforces Round 72 (Rated for Div. 2)E. Sum Queries?(线段树区间合并)

https://codeforc.es/contest/1217/problem/E 建立9棵数位线段树维护区间最小值和次小值,建议用struct建树方便进行区间合并 1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 #define iter ::it

CF1217E Sum Queries? (线段树)

完了,前几天才说 edu 的 DEF 都不会,现在打脸了吧 qwq 其实在刚说完这句话 1min 就会了 D,3min 就会了 E 发现,对于大小 \(\ge 3\) 的不平衡集合,它至少有一个大小为 \(2\) 的子集是不平衡的. 证明,发现对于大小为 \(2\) 的集合,平衡当且仅当两数的数位交为空(对于任意一位,至多一个数在这一位上不是 \(0\)). 反证一波,如果大集合没有大小为 \(2\) 的不平衡集合,那么任意两数的数位交都为空,那么大集合也是平衡的,矛盾了. 所以,只需要考虑大小

[email&#160;protected] [307] Range Sum Query - Mutable / 线段树模板

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. The update(i, val) function modifies nums by updating the element at index i to val. Example: Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2

CF920F SUM and REPLACE 题解

CF920F SUM and REPLACE 线段树例题解析合集 和模板的不同之处在于修改时是改为每个数的约数个数,不难发现,当一个数x<=2时,x的约数个数与本身相等,修改多少次多不会在改变 先预处理出每个数的约数个数,用线段树维护区间最大值,若<=2,则直接结束递归 对于>2的数都要暴力修改,但由于每个数的约数个数下降很快,几次后便降到<=2,所以复杂度优秀(大约是nlogn?) 这题与CF438D The Child and Sequence(区间取模),类似,也可以维护区间