hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
2016-02-27 23:38
316 查看
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 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.
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
题意:给你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|1 using 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; }
相关文章推荐
- hdoj 5631 Rikka with Graph 【并查集】
- 基于Python的数据可视化 matplotlib seaborn pandas
- 论下载程序升级包在手机移动网和WiFi的不同
- 设置mysql的最大连接数
- 【MOOC EXP】Linux内核分析实验一报告
- 一批违规网络大V账号被关闭
- 一批违规网络大V账号被关闭
- python中map()与zip()操作方法
- rsync+inotify实现数据实时同步
- Android系统之G-sensor
- css学习(一)-CSS基础、css选择器
- AFN3.0与2.0分别做了哪些处理
- hdoj 5630 Rikka with Chess 【水题】
- Unity3D 5 官方教程:SpeedTree/LOD Trees
- Notepad++插件Emmet不工作解决办法
- python之字符串
- android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity
- NYOJ 某种序列
- 【线段树】【二分】[PA2015][BZOJ4293]Siano
- lucky string