Rikka with Phi
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 655 Accepted Submission(s): 214
Problem Description
Rikka and Yuta are interested in Phi function (which is known as Euler's totient function).
Yuta gives Rikka an array A[1..n] of positive integers, then Yuta makes m queries.
There are three types of queries:
1lr
Change A[i] into φ(A[i]) , for all i∈[l,r] .
2lrx
Change A[i] into x , for all i∈[l,r] .
3lr
Sum up A[i] , for all i∈[l,r] .
Help Rikka by computing the results of queries of type 3.
Yuta gives Rikka an array A[1..n] of positive integers, then Yuta makes m queries.
There are three types of queries:
1lr
Change A[i] into φ(A[i]) , for all i∈[l,r] .
2lrx
Change A[i] into x , for all i∈[l,r] .
3lr
Sum up A[i] , for all i∈[l,r] .
Help Rikka by computing the results of queries of type 3.
Input
The first line contains a number
T(T≤100)
——The number of the testcases. And there are no more than 2 testcases with
n>105
For each testcase, the first line contains two numbers n,m(n≤3×105,m≤3×105) 。
The second line contains n numbers A[i]
Each of the next m lines contains the description of the query.
It is guaranteed that 1≤A[i]≤107 At any moment.
For each testcase, the first line contains two numbers n,m(n≤3×105,m≤3×105) 。
The second line contains n numbers A[i]
Each of the next m lines contains the description of the query.
It is guaranteed that 1≤A[i]≤107 At any moment.
Output
For each query of type 3, print one number which represents the answer.
Sample Input
1 10 10 56 90 33 70 91 69 41 22 77 45 1 3 9 1 1 10 3 3 8 2 5 6 74 1 1 8 3 1 9 1 2 10 1 4 9 2 8 8 69 3 3 9
Sample Output
80 122 86
Source
Recommend
hujie
题意:有3种区间操作:
1.是把区间内的所有数变成它的欧拉函数值
2.是把区间所有数都变成一个数x
3.是查询区间和
解题思路:线段树,维护区间内的数是否相同,区间更新即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int x[10000009], n, m;
LL sum[300009 << 2], lazy[300009 << 2];
void init()
{
x[1] = 1;
for (int i = 2; i < 10000009; i++) x[i] = i;
for (int i = 2; i < 10000009; i++)
if (x[i] == i)
for (int j = i; j < 10000009; j += i) x[j] = x[j] / i*(i - 1);
}
void Push(int k, int l,int r)
{
lazy[k << 1] = lazy[k << 1 | 1] = lazy[k];
int mid = (l + r) >> 1;
sum[k << 1] = (LL)lazy[k] * (mid - l + 1);
sum[k << 1 | 1] = (LL)lazy[k] * (r - mid);
lazy[k] = -1;
}
void Merge(int k)
{
sum[k] = sum[k << 1] + sum[k << 1 | 1];
lazy[k] = ((lazy[k << 1] == lazy[k << 1 | 1]) ? lazy[k << 1] : -1);
}
void build(int k, int l, int r)
{
if (l == r) { scanf("%d", &lazy[k]); sum[k] = lazy[k]; return; }
int mid = l + r >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
Merge(k);
}
void update(int k, int l, int r, int ll, int rr, int val,int type)
{
if (ll <= l&&r <= rr&&!type) { lazy[k] = val; sum[k] = (LL)(r - l + 1)*val; return; }
if (ll <= l&&r <= rr&&type&&lazy[k] != -1) { lazy[k] = x[lazy[k]]; sum[k] = (LL)lazy[k] * (r - l + 1); return; }
int mid = l + r >> 1;
if (lazy[k]!=-1) Push(k, l, r);
if (ll <= mid) update(k << 1, l, mid, ll, rr, val,type);
if (rr > mid) update(k << 1 | 1, mid + 1, r, ll, rr, val,type);
Merge(k);
}
LL getans(int k, int l, int r, int ll, int rr)
{
if (ll <= l&&r <= rr) return sum[k];
int mid = l + r >> 1;
LL ans = 0;
if (lazy[k]!=-1) Push(k, l, r);
if (ll <= mid) ans += getans(k << 1, l, mid, ll, rr);
if (rr > mid) ans += getans(k << 1 | 1, mid + 1, r, ll, rr);
return ans;
}
int main()
{
init();
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
build(1, 1, n);
while (m--)
{
int p, l, r, c;
scanf("%d%d%d", &p, &l, &r);
if (p == 1) update(1, 1, n, l, r,1,1);
if (p == 2) scanf("%d", &c), update(1, 1, n, l, r, c,0);
if (p == 3) printf("%lld\n", getans(1, 1, n, l, r));
}
}
return 0;
}