HDU 5634 Rikka with Phi(线段树)
来源:互联网 发布:淘宝违规申诉成功率 编辑:程序博客网 时间:2024/06/10 03:10
题目链接:点击打开链接
题意:有3种区间操作, 1是把区间内的所有数变成它的欧拉函数值, 2是把区间所有数都变成一个数x,3是查询区间和。
思路:后两个操作就是线段树的区间修改和求和, 没什么好说的。
题解说用平衡树(弱不会), 不过大致思路线段树同样可以维护, 因为一个数进行最多phiO(logn)次就会变成1, 所以我们可以在递归结束,向上传标记的时候顺便看看其子区间是不是都等于1, 是就合并起来, 给这个点重新标记。
细节参见代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<vector>#include<stack>#include<bitset>#include<cstdlib>#include<cmath>#include<set>#include<list>#include<deque>#include<map>#include<queue>using namespace std;typedef long long ll;typedef long double ld;const ld EPS = 1e-9, PI = 3.1415926535897932384626433832795;const int mod = 1000000000 + 7;const int INF = int(1e9);const ll INF64 = ll(1e18);const int maxn = 300000 + 10;int T, n, m, v, id, l, r, x;ll sum[maxn<<2], setv[maxn<<2];#define Max 10000010ll euler[Max] = {0};void Init(){ euler[1]=1; for(ll i=2;i<Max;i++) euler[i]=i; for(ll i=2;i<Max;i++) if(euler[i]==i) for(ll j=i;j<Max;j+=i) euler[j]=euler[j]/i*(i-1);}void PushUp(int o) { sum[o] = sum[o<<1] + sum[o<<1|1]; if(setv[o<<1] == setv[o<<1|1]) setv[o] = setv[o<<1]; else setv[o] = 0;}void build(int l, int r, int o) { int m = (l + r) >> 1; sum[o] = 0; setv[o] = 0; if(l == r) { scanf("%d",&v); sum[o] = setv[o] = v; return ; } build(l, m, o<<1); build(m+1, r, o<<1|1); PushUp(o);}void pushdown(int l, int r, int o) { if(setv[o]) { int m = (l + r) >> 1; setv[o<<1] = setv[o<<1|1] = setv[o]; sum[o<<1] = (ll)(m - l + 1) * setv[o]; sum[o<<1|1] = (ll)(r - m) * setv[o]; setv[o] = 0; }}void update(int L, int R, int v, int l, int r, int o) { int m = (l + r) >> 1; if(L <= l && r <= R) { setv[o] = (ll)v; sum[o] = (ll)v * (r - l + 1); return ; } pushdown(l, r, o); if(L <= m) update(L, R, v, l, m, o<<1); if(m < R) update(L, R, v, m+1, r, o<<1|1); PushUp(o);}void haha(int L, int R, int l, int r, int o) { int m = (l + r) >> 1; if(setv[o] && L <= l && r <= R) { setv[o] = euler[setv[o]]; sum[o] = setv[o] * (r - l + 1); return ; } if(l == r) return ; pushdown(l, r, o); if(L <= m) haha(L, R, l, m, o<<1); if(m < R) haha(L, R, m+1, r, o<<1|1); PushUp(o);}ll query(int L, int R, int l, int r, int o) { int m = (l + r) >> 1; if(L <= l && r <= R) { return sum[o]; } pushdown(l, r, o); ll ans = 0; if(L <= m) ans += query(L, R, l, m, o<<1); if(m < R) ans += query(L, R, m+1, r, o<<1|1); PushUp(o); return ans;}int main() { Init(); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(1, n, 1); while(m--) { scanf("%d%d%d",&id,&l,&r); if(id == 1) haha(l, r, 1, n, 1); else if(id == 2) { scanf("%d",&x); update(l, r, x, 1, n, 1); } else printf("%I64d\n",query(l, r, 1, n, 1)); } } return 0;}
0 0
- 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(线段树+欧拉函数)
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- HDU 5634 Rikka with Phi
- hdoj 5634 Rikka with Phi 【线段树 + 欧拉】
- HDU5634 Rikka with Phi(线段树)
- 【hdu5634】Rikka with Phi(线段树+欧拉函数)
- HDU 5828 Rikka with Sequence(线段树+小优化)
- HDU 5828 Rikka with Sequence(线段树)
- Hdu-5828 Rikka with Sequence(线段树)
- HDU-5828-Rikka with Sequence(线段树)
- 【HDU 5828】Rikka with Sequence(线段树)
- HDU 5828 Rikka with Sequence(线段树)
- iOS中跳转控制器隐藏底部tabBar
- linux设备驱动归纳总结(四):3.抢占和上下文切换
- 分布式消息队列(Message Queue)系统:kafka
- github配置密钥
- 什么是REST?以及RESTful的实现
- HDU 5634 Rikka with Phi(线段树)
- 内部类相关知识-java基础
- java,异常处理,throwable和try...catch[zz]
- Eclipse错误:Problems opening an editor Reason: [Project Name] does not exist解决办法
- C语言之模块化例子(编译环境CODEBLOCK,多文件编译)
- APP测试功能点总结
- 内部类题
- Flash、RAM、ROM的区别
- 摘录之 JAVA 性能 优化 总结