HDU 5634-Rikka with Phi(线段树区间更新)

来源:互联网 发布:杨师傅ug编程百度网盘 编辑:程序博客网 时间:2024/06/07 06:33

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.

 

Input
The first line contains a number T(T100) ——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(n3×105,m3×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 1A[i]107 At any moment.
 

Output
For each query of type 3, print one number which represents the answer.
 

Sample Input
110 1056 90 33 70 91 69 41 22 77 451 3 91 1 103 3 82 5 6 741 1 83 1 91 2 101 4 92 8 8 693 3 9
 

Sample Output
8012286
 



#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 longconst 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;}


0 0
原创粉丝点击