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 ...
随机推荐
- ecshop启用gzip后,后台不能打开不能访问的问题
上传测试的时候,站点显示无法打开.随后我用网址打开根目录的robots文件.图片.静态页···全部可以正常打开··· 我尴尬···一一检查后,我就怀疑是不是客户当初设置gzip压缩的问题了.但连后台都 ...
- C语言作业总结
.## 一.我学到的内容 二.我的收获 作业 学到的知识点简介 C语言I博客作业01 学习了markdown语法. C语言I博客作业02 学习了<提问的智慧>. C语言I博客作业03 了解 ...
- Appium+Python之生成html测试报告
思考:测试用例执行后,如何生成一个直观漂亮的测试报告呢? 分析:1.unittest单元测试框架本身带有一个textTestRunner类,可以生成txt文本格式的测试报告,但是页面不够直观 2.我们 ...
- python pickle模块的用法
pickle用于python特有的类型,和python的数据类型间进行转换,提供四个功能 dumps,dump,loads,load. pickle 的用法 #pickle.dumps 将数据通过特殊 ...
- Codeforces Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
传送门 A. XORinacci 手玩三四项发现序列就是 $a,b,a\ xor\ b,a,b,...$,直接输出即可 #include<iostream> #include<cst ...
- Java ——数字图像处理(Java Graphics及其API简介)
1.创建一个Graphics对象BufferedImage bi = new BufferedImage(120,120, BufferedImage.TYPE_INT_ARGB);Graphics2 ...
- nginx负载均衡的搭建和简单例子
一,nginx 下载地址:http://nginx.org/en/download.html 二,下载对应版本 三,打开下载的安装包:如下图 四,运行nginx.exe 1,这个是时候,程序运行都是一 ...
- vue项目报错,解决Module build failed: Error: Cannot find module 'node-sass' 问题
1.报错问题 1 E:\WebStormFile\treehole-manage>npm run dev > xc-ui-pc-sysmanage@1.0.0 dev E:\WebStor ...
- glibc2.22
- git 和码云的上传文件代码操作
Git与Github的连接与使用 一 安装git软件 1.git介绍 ''' git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. 分布式相比于集中式的最大区别在于开发 ...