Codeforces 920F-SUM and REPLACE
2018-02-07 21:44
399 查看
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, D(2) = 2 (2 is
divisible by 1 and 2), D(6) = 4 (6 is
divisible by 1, 2, 3 and 6).
You are given an array a of n integers.
You have to process two types of queries:
REPLACE l r —
for every
![](http://codeforces.com/predownloaded/33/4e/334e338c9804dd0f2ad09a404a1b0b0a64693034.png)
replace ai with D(ai);
SUM l r —
calculate
![](http://codeforces.com/predownloaded/85/f3/85f3b14f57b1f05c219263ba36a0274dd8e82c2f.png)
.
Print the answer for each SUM query.
Input
The first line contains two integers n and m (1 ≤ n, m ≤ 3·105)
— the number of elements in the array and the number of queries to process, respectively.
The second line contains n integers a1, a2,
..., an (1 ≤ ai ≤ 106)
— the elements of the array.
Then m lines follow, each containing 3 integers ti, li, ri denoting i-th
query. If ti = 1,
then i-th query is REPLACE li ri,
otherwise it's SUM liri (1 ≤ ti ≤ 2, 1 ≤ li ≤ ri ≤ n).
There is at least one SUM query.
Output
For each SUM query print the answer to it.
Example
input
output
题意:有n个数,有两种操作,一种是求出l~r的数字和,另一种是将l~r之间的所有数变为它们的因子数
解题思路:线段树,不过若一个区间的最大值小于等于2就没必要更新下去了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int n, q;
LL x[300009], ma[300009 << 2], sum[300009 << 2];
int p, l, r;
int ans[1000009];
void init()
{
for (int i = 1; i <= 1000000; i++)
for (int j = i; j <= 1000000; j += i)
ans[j]++;
}
void build(int k, int l, int r)
{
if (l == r)
{
scanf("%lld", &x[l]);
ma[k] = sum[k] = x[l];
return;
}
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void update(int k, int l, int r, int ll, int rr)
{
if (ma[k] <= 2LL) return;
if (l == r) { ma[k] = sum[k] = x[l] = ans[x[l]]; return; }
int mid = (l + r) >> 1;
if (ll <= mid) update(k << 1, l, mid, ll, rr);
if (rr > mid) update(k << 1 | 1, mid + 1, r, ll, rr);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
LL query(int k, int l, int r, int ll, int rr)
{
if (l >= ll && r <= rr) return sum[k];
int mid = (l + r) >> 1;
LL ans = 0;
if (ll <= mid) ans += query(k << 1, l, mid, ll, rr);
if (rr > mid) ans += query(k << 1 | 1, mid + 1, r, ll, rr);
return ans;
}
int main()
{
init();
while (~scanf("%d %d", &n, &q))
{
build(1, 1, n);
while (q--)
{
scanf("%d %d %d", &p, &l, &r);
if (p == 1) update(1, 1, n, l, r);
else printf("%lld\n", query(1, 1, n, l, r));
}
}
return 0;
}
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, D(2) = 2 (2 is
divisible by 1 and 2), D(6) = 4 (6 is
divisible by 1, 2, 3 and 6).
You are given an array a of n integers.
You have to process two types of queries:
REPLACE l r —
for every
![](http://codeforces.com/predownloaded/33/4e/334e338c9804dd0f2ad09a404a1b0b0a64693034.png)
replace ai with D(ai);
SUM l r —
calculate
![](http://codeforces.com/predownloaded/85/f3/85f3b14f57b1f05c219263ba36a0274dd8e82c2f.png)
.
Print the answer for each SUM query.
Input
The first line contains two integers n and m (1 ≤ n, m ≤ 3·105)
— the number of elements in the array and the number of queries to process, respectively.
The second line contains n integers a1, a2,
..., an (1 ≤ ai ≤ 106)
— the elements of the array.
Then m lines follow, each containing 3 integers ti, li, ri denoting i-th
query. If ti = 1,
then i-th query is REPLACE li ri,
otherwise it's SUM liri (1 ≤ ti ≤ 2, 1 ≤ li ≤ ri ≤ n).
There is at least one SUM query.
Output
For each SUM query print the answer to it.
Example
input
7 6 6 4 1 10 3 2 4 2 1 7 2 4 5 1 3 5 2 4 4 1 5 7 2 1 7
output
30 13 4 22
题意:有n个数,有两种操作,一种是求出l~r的数字和,另一种是将l~r之间的所有数变为它们的因子数
解题思路:线段树,不过若一个区间的最大值小于等于2就没必要更新下去了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int n, q;
LL x[300009], ma[300009 << 2], sum[300009 << 2];
int p, l, r;
int ans[1000009];
void init()
{
for (int i = 1; i <= 1000000; i++)
for (int j = i; j <= 1000000; j += i)
ans[j]++;
}
void build(int k, int l, int r)
{
if (l == r)
{
scanf("%lld", &x[l]);
ma[k] = sum[k] = x[l];
return;
}
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void update(int k, int l, int r, int ll, int rr)
{
if (ma[k] <= 2LL) return;
if (l == r) { ma[k] = sum[k] = x[l] = ans[x[l]]; return; }
int mid = (l + r) >> 1;
if (ll <= mid) update(k << 1, l, mid, ll, rr);
if (rr > mid) update(k << 1 | 1, mid + 1, r, ll, rr);
ma[k] = max(ma[k << 1], ma[k << 1 | 1]);
sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
LL query(int k, int l, int r, int ll, int rr)
{
if (l >= ll && r <= rr) return sum[k];
int mid = (l + r) >> 1;
LL ans = 0;
if (ll <= mid) ans += query(k << 1, l, mid, ll, rr);
if (rr > mid) ans += query(k << 1 | 1, mid + 1, r, ll, rr);
return ans;
}
int main()
{
init();
while (~scanf("%d %d", &n, &q))
{
build(1, 1, n);
while (q--)
{
scanf("%d %d %d", &p, &l, &r);
if (p == 1) update(1, 1, n, l, r);
else printf("%lld\n", query(1, 1, n, l, r));
}
}
return 0;
}
相关文章推荐
- Codeforces-920F:SUM and REPLACE(set+树状数组)
- Codeforces 920F - SUM and REPLACE【线段树】
- Codeforces 920F - SUM and REPLACE(线段树)
- codeforces 703D Mishka and Interesting sum(数状数组维护前缀)
- CodeForces 703D Mishka and Interesting sum (树状数组 区间偶数异或)
- Codeforces 703D Mishka and Interesting sum 离线+树状数组
- CodeForces 703D Mishka and Interesting sum
- Codeforces #277.5 (Div. 2) C. Given Length and Sum of Digits...(简单贪心)
- CodeForces 703D Mishka and Interesting sum (树状数组处理异或和)
- Codeforces 489C - Given Length and Sum of Digits...(贪心)
- Codeforces 276C Little Girl and Maximum Sum(线段树的区间更新)
- Codeforces 276C Little Girl and Maximum Sum【贪心】
- codeforces D. Mishka and Interesting sum 求区间内不同数的异或值
- codeforces CF703D Mishka and Interesting sum 树状数组
- codeforces#277.5 C. Given Length and Sum of Digits
- CF EDU 37 F SUM and REPLACE 【线段树区间更新中的单点更新】 好题!
- Codeforces 703D Mishka and Interesting sum (树状数组求区间内不同的数的异或和)
- Codeforces-489C-Given Length and Sum of Digits...
- Educational Codeforces Round 37 (Rated for Div. 2) F. SUM and REPLACE(线段树,区间更新)
- CodeForces 703D Mishka and Interesting sum