Rikka with Phi
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 312 Accepted Submission(s): 103
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
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
const int maxn = 3e5 + 10;
const int phimaxn = 1e7 + 10;
int phi[phimaxn] = { 0 };
void getphi()
{
phi[1] = 1;
for (int i = 2; i < phimaxn; i++)
{
if (!phi[i])
{
for (int j = i; j < phimaxn; j += i)
{
if (!phi[j])
phi[j] = j;
phi[j] = phi[j] / i*(i - 1);
}
}
}
}
LL sum[maxn << 2], lazy[maxn << 2];
void PushUp(int l, int r, int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
if (lazy[rt << 1] == lazy[rt << 1 | 1])
lazy[rt] = lazy[rt << 1];
else
lazy[rt] = 0; //之前因为这个没写所以错了
}
void change(int rt, int l, int r)
{
sum[rt] = lazy[rt] * (r - l + 1);
}
void PushDown(int l, int r, int rt)
{
if (lazy[rt])
{
lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
int m = (l + r) >> 1;
change(rt << 1, l, m);
change(rt << 1 | 1, m + 1, r);
lazy[rt] = 0;
}
}
void build(int l, int r, int rt)
{
if (l == r)
{
scanf("%I64d", &sum[rt]);
lazy[rt] = sum[rt];
return;
}
lazy[rt] = sum[rt] = 0;
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(l, r, rt);
}
void dophi(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R&&lazy[rt])
{
sum[rt] = (LL)(r - l + 1)*phi[lazy[rt]];
lazy[rt] = (LL)phi[lazy[rt]];
return;
}
PushDown(l, r, rt);
int m = (l + r) >> 1;
if (L <= m) dophi(L, R, lson);
if (R > m) dophi(L, R, rson);
PushUp(l, r, rt);
}
void update(int L, int R, int c, int l, int r, int rt)
{
if (L <= l&&r <= R)
{
lazy[rt] = (LL)c;
change(rt, l, r);
return;
}
PushDown(l, r, rt);
int m = (l + r) >> 1;
if (L <= m) update(L, R, c, lson);
if (R > m) update(L, R, c, rson);
PushUp(l, r, rt);
}
LL query(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
{
return sum[rt];
}
PushDown(l, r, rt);
LL ans = 0;
int m = (l + r) >> 1;
if (L <= m)
ans += query(L, R, lson);
if (R > m)
ans += query(L, R, rson);
PushUp(l, r, rt);
return ans;
}
int main()
{
getphi();
int T;
scanf("%d", &T);
while (T--)
{
int n, m;
scanf("%d%d", &n, &m);
build(1, n, 1);
for (int i = 0; i < m; i++)
{
int c, l, r, x;
scanf("%d%d%d", &c, &l, &r);
if (c == 1)
{
dophi(l, r, 1, n, 1);
}
else if (c == 2)
{
scanf("%d", &x);
update(l, r, x, 1, n, 1);
}
else if (c == 3)
{
printf("%I64d\n", query(l, r, 1, n, 1));
}
}
}
return 0;
}