HDU 5634 Rikka with Phi
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634
--------------------------------------------------------------------------------------------
官方题解上给的是用平衡树写 不过用类似的思路 也是可以用线段树去写的
操作$2$区间赋为相同值可以直接按照常规的线段树的题目去写
操作$1$是只减不增的 而且最多$log$次会减少到$1$
所以大量使用$1$操作会出现许多连续的$1$
当访问到区间都是一个值显然可以直接返回结果
而在这之前我们变可以把区间不为相同值的进行暴力取$phi$
尽管操作$2$会使区间值增加 但如果把连续的相同值算作$1$个区间的话
操作$2$每次最多只会增加$1$个区间 所以均摊下来并不会使操作$1$的复杂度增加
最终复杂度也是$O((n + m)logn)$的
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1e7, L = 7e5, T = 3e5 + ;
bool used[N + ];
int phi[N + ], p[L];
int a[T], flag[T << ];
long long sum[T << ];
int len, t, n, m;
void getprime()
{
phi[] = ;
for(int i = ; i <= N; ++i)
{
if(! used[i])
{
p[++len] = i;
phi[i] = i - ;
}
for(int j = ; j <= len && i * p[j] <= N; ++j)
{
used[i * p[j]] = ;
if(i % p[j] == )
{
phi[i * p[j]] = phi[i] * p[j];
break;
}
else
phi[i * p[j]] = phi[i] * (p[j] - );
}
}
}
void build(int x, int L, int R)
{
if(L == R)
{
sum[x] = flag[x] = a[L];
return;
}
int mid = (L + R) >> ;
build(x << , L, mid);
build(x << | , mid + , R);
sum[x] = sum[x << ] + sum[x << | ];
flag[x] = (flag[x << ] == flag[x << | ] ? flag[x << ] : );
}
void update2(int x, int L, int R, int tl, int tr, int y)
{
if(L <= tl && tr <= R)
{
flag[x] = y;
sum[x] = (long long)flag[x] * (tr - tl + );
return;
}
int mid = (tl + tr) >> ;
if(flag[x])
{
update2(x << , tl, mid, tl, mid, flag[x]);
update2(x << | , mid + , tr, mid + , tr, flag[x]);
}
if(L <= mid)
update2(x << , L, R, tl, mid, y);
if(mid < R)
update2(x << | , L, R, mid + , tr, y);
sum[x] = sum[x << ] + sum[x << | ];
flag[x] = (flag[x << ] == flag[x << | ] ? flag[x << ] : );
}
void update1(int x, int L, int R, int tl, int tr)
{
if(flag[x] && L <= tl && tr <= R)
{
flag[x] = phi[flag[x]];
sum[x] = (long long)flag[x] * (tr - tl + );
return;
}
int mid = (tl + tr) >> ;
if(flag[x])
{
update2(x << , tl, mid, tl, mid, flag[x]);
update2(x << | , mid + , tr, mid + , tr, flag[x]);
}
if(L <= mid)
update1(x << , L, R, tl, mid);
if(mid < R)
update1(x << | , L, R, mid + , tr);
sum[x] = sum[x << ] + sum[x << | ];
flag[x] = (flag[x << ] == flag[x << | ] ? flag[x << ] : );
}
long long query(int x, int L, int R, int tl, int tr)
{
if(L <= tl && tr <= R)
return sum[x];
int mid = (tl + tr) >> ;
if(flag[x])
{
update2(x << , tl, mid, tl, mid, flag[x]);
update2(x << | , mid + , tr, mid + , tr, flag[x]);
}
long long re = ;
if(L <= mid)
re += query(x << , L, R, tl, mid);
if(mid < R)
re += query(x << | , L, R, mid + , tr);
return re;
}
int main()
{
getprime();
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%d", &a[i]);
build(, , n);
int op, x, y, z;
while(m--)
{
scanf("%d%d%d", &op, &x, &y);
if(op == )
update1(, x, y, , n);
else if(op == )
{
scanf("%d", &z);
update2(, x, y, , n, z);
}
else
printf("%lld\n", query(, x, y, , n));
}
}
return ;
}
HDU 5634 Rikka with Phi的更多相关文章
- HDU 5634 Rikka with Phi 线段树
题意:bc round 73 div1 D 中文题面 分析:注意到10^7之内的数最多phi O(log(n))次就会变成1, 因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护. 每次求p ...
- 2018.07.03 HDU Rikka with Phi(线段树)
Rikka with Phi Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) P ...
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- HDU 6088 - Rikka with Rock-paper-scissors | 2017 Multi-University Training Contest 5
思路和任意模数FFT模板都来自 这里 看了一晚上那篇<再探快速傅里叶变换>还是懵得不行,可能水平还没到- - 只能先存个模板了,这题单模数NTT跑了5.9s,没敢写三模数NTT,可能姿势太 ...
- HDU 5831 Rikka with Parenthesis II(六花与括号II)
31 Rikka with Parenthesis II (六花与括号II) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...
- HDU5634 Rikka with Phi 线段树
// HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...
- Rikka with Phi 线段树
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...
- HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5
思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...
- HDU 6093 - Rikka with Number | 2017 Multi-University Training Contest 5
JAVA+大数搞了一遍- - 不是很麻烦- - /* HDU 6093 - Rikka with Number [ 进制转换,康托展开,大数 ] | 2017 Multi-University Tra ...
随机推荐
- python 入门学习之anaconda篇
还没下载的同学先点击这里进入anaconda官方网站进行下载. 然后点击安装,注意的是这里 安装好了之后呢,我们就开始进行Conda的环境管理,Conda的环境管理功能允许我们同时安装 若干不同版本的 ...
- python+selenium的frame表单切换
switch_to.frame() 切换frame switch_to.default_content() 切 ...
- python+selenium的WebElement对象操作
webelement对象操作 webelement对象是selenium中所有元素的父类,也就是webelement对象拥有的方法,其它元素对象都会有: 只是不同的对象在调用特定方法时,效果是不一样的 ...
- vue数据响应式的一些注意点
有关对象属性值不触发视图更新的情况: Vue 不能检测到对象属性的添加或删除,由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 ...
- 短篇文档兼职看过来 python 课后作业 assignment project
文档兼职 开题报告 读后感 课后作业 等 代写 编程,Java ,Python,R,等语言的,国内外课程作业指导,写作. 有经验,有作品,成交快,放心! 可联系 QQ 550987425
- 【JAVA】Java 异常中e的getMessage()和toString()方法的异同
参考链接 CSDN: Java 异常中e的getMessage()和toString()方法的异同 示例代码1: public class TestInfo { private static ...
- java 进销存管理 商户管理 库存管理 springmvc SSM 项目源码
统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM 普 ...
- 初入vue.js(1)
本文章属于个人在学习vue的随笔,留作与大家分享,技术交流之用,如果有错误,请大家多多指正.谢谢 首先说一下vue的使用方式: vue的使用方式一共有两种,第一种是直接在官网上下载vue.js的文件, ...
- ReactiveCocoa详解
最近看了大神的博客后,感觉该对ReactiveCocoa做一个了断了. 首先大致的对以下关于ReactiveCocoa内容做一个简单的总结,其他的后续更新 1.ReactiveCocoa的操作思想 2 ...
- 使用Varnish加速Web
通过配置Varnish缓存服务器,实现如下目标: - 使用Varnish加速后端Web服务 - 代理服务器可以将远程的Web服务器页面缓存在本地 - 远程Web服务器对客户端用户是透明的 - 利用缓存 ...