hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
来源:互联网 发布:word表格数据求和 编辑:程序博客网 时间:2024/06/11 04:58
Rikka with Phi
Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 207 Accepted Submission(s): 64
Problem Description
Rikka and Yuta are interested in Phi function (which is known as Euler's totient function).
Yuta gives Rikka an arrayA[1..n] of positive integers, then Yuta makes m queries.
There are three types of queries:
1lr
ChangeA[i] into φ(A[i]) , for all i∈[l,r] .
2lrx
ChangeA[i] into x , for all i∈[l,r] .
3lr
Sum upA[i] , for all i∈[l,r] .
Help Rikka by computing the results of queries of type 3.
Yuta gives Rikka an array
There are three types of queries:
Change
Change
Sum up
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 numbersn,m(n≤3×105,m≤3×105) 。
The second line containsn numbers A[i]
Each of the nextm lines contains the description of the query.
It is guaranteed that1≤A[i]≤107 At any moment.
For each testcase, the first line contains two numbers
The second line contains
Each of the next
It is guaranteed that
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
题意:给你n个数和m次操作。
1 x y 表示将区间[x, y]里面的数变为自己的欧拉函数。
2 x y v 表示将区间[x, y]里面的数修改为v。
3 x y 表示求区间[x, y]的和。
思路:n<=10^7的数,最多进行logn次欧拉函数求解就会变成1。
对于操作2,可以直接区间更新。
对于操作1,我们标记 每个区间是否满足直接区间更新的条件——条件为左、右子区间的所有数全部相等。若某一个区间满足条件,可以用一个变量记录当前区间的元素值。这样在更新时,没必要直接更新到底。初始显然只有叶子区间,之后每次两个子区间改变,我们都需要将信息向上传递。
AC代码:
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;const int MAXN = 3*1e5+1;const int MAXM = 1e7+1;LL euler[MAXM];void Geteuler(){ memset(euler, 0, sizeof(euler)); euler[1] = 1; for(LL i = 2; i < MAXM; i++) if(!euler[i]) for(LL j = i; j < MAXM; j += i){ if(!euler[j]) euler[j] = j; euler[j] = euler[j] / i * (i-1); }}struct Tree{ int l, r, len; LL sum, lazy;};Tree tree[MAXN<<2];void PushUp(int o){ tree[o].sum = tree[ll].sum + tree[rr].sum; if(tree[ll].lazy == tree[rr].lazy) tree[o].lazy = tree[ll].lazy; else tree[o].lazy = 0;}void PushDown(int o){ if(tree[o].lazy) { tree[ll].lazy = tree[rr].lazy = tree[o].lazy; tree[ll].sum = tree[o].lazy * tree[ll].len; tree[rr].sum = tree[o].lazy * tree[rr].len; }}void Build(int o, int l, int r){ tree[o].l = l; tree[o].r = r; tree[o].len = r - l + 1; if(l == r) { scanf("%lld", &tree[o].sum); tree[o].lazy = tree[o].sum; return ; } int mid = (l + r) >> 1; Build(ll, l, mid); Build(rr, mid+1, r); PushUp(o);}void Update1(int o, int L, int R){ if(tree[o].lazy && L == tree[o].l && R == tree[o].r) { tree[o].sum = euler[tree[o].lazy] * tree[o].len; tree[o].lazy = euler[tree[o].lazy]; return ; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) Update1(ll, L, R); else if(L > mid) Update1(rr, L, R); else { Update1(ll, L, mid); Update1(rr, mid+1, R); } PushUp(o);}void Update2(int o, int L, int R, int v){ if(L == tree[o].l && R == tree[o].r) { tree[o].lazy = v; tree[o].sum = 1LL * v * tree[o].len; return ; } PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) Update2(ll, L, R, v); else if(L > mid) Update2(rr, L, R, v); else { Update2(ll, L, mid, v); Update2(rr, mid+1, R, v); } PushUp(o);}LL Query(int o, int L, int R){ if(L == tree[o].l && R == tree[o].r) return tree[o].sum; PushDown(o); int mid = (tree[o].l + tree[o].r) >> 1; if(R <= mid) return Query(ll, L, R); else if(L > mid) return Query(rr, L, R); else return Query(ll, L, mid) + Query(rr, mid+1, R);}int main(){ Geteuler(); int t; scanf("%d", &t); while(t--) { int n, m; scanf("%d%d", &n, &m); Build(1, 1, n); while(m--) { int op, x, y, v; scanf("%d%d%d", &op, &x, &y); if(op == 1) Update1(1, x, y); else if(op == 2) {scanf("%d", &v); Update2(1, x, y, v);} else if(op == 3) printf("%lld\n", Query(1, x, y)); } } return 0;}
0 0
- hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
- 【hdu5634】Rikka with Phi(线段树+欧拉函数)
- HDU 5634 Rikka with Phi(线段树+欧拉函数)
- HDU 5634 Rikka with Phi (线段树)
- [均摊 平衡树 || 线段树] HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi(线段树)
- HDU 5634 Rikka with Phi(暴力、线段树)
- HDU 5634-Rikka with Phi(线段树区间更新)
- HDU5634 Rikka with Phi(线段树)
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- HDU5634-Rikka with Phi
- [题解]hdu5634 Rikka with Phi
- hdu5828 Rikka with Sequence(线段树)
- 【HDU5828】Rikka with Sequence(线段树)
- 欧拉函数PHI
- 欧拉函数PHI
- 玩转Red5+Flex(3)—— Red5第一个例子之HelloWorld
- IntelliJ IDEA 使用心得与常用快捷键
- Linux中查看CPU信息
- 计算机是如何执行程序的(以汇编一个简单的C程序,分析汇编代码为例)
- NOJ——1658平方和(自然数平方和公式和取模法则)
- hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
- 手把手交大家在mac上用VMWare虚拟机装Linux-Ubuntu--及Ubuntu安装Vmware Tools
- 大型分布式网站架构技术总结
- Linux文件系统的实现
- 黑马第一天笔记
- win7+gvim7.4+spf13使用自动补全编写python脚本
- 判断变量定义和变量为空问题
- JSP/Servlet相关技术1
- Ubuntu11.04不能连无线网络的解决方法