Rikka with Phi 线段树
There is a very long board with length L centimeter, L is a positive integer, so we can evenly divide the board into L segments, and they are labeled by 1, 2, ... L from left to right, each is 1 centimeter long. Now we have to color the board - one segment with only one color. We can do following two operations on the board:
1. "C A B C" Color the board from segment A to segment B with color C.
2. "P A B" Output the number of different colors painted between segment A and segment B (including).
In our daily life, we have very few words to describe a color (red, green, blue, yellow…), so you may assume that the total number of different colors T is very small. To make it simple, we express the names of colors as color 1, color 2, ... color T. At the beginning, the board was painted in color 1. Now the rest of problem is left to your.
Input
Output
Sample Input
2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2
Sample Output
2
1
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
typedef long long LL;
const int MAXN = 1e7 + ;
const int N = 3e5 + ;
LL euler[MAXN];
void geteuler()
{
memset(euler, , sizeof(euler));
euler[] = ;
for (LL i = ; i < MAXN; i++)
{
if (!euler[i])
for (LL j = i; j < MAXN; j += i)
{
if (!euler[j]) euler[j] = j;
euler[j] = euler[j] / i * (i - );
}
}
}
struct node
{
int l, r;
LL sum, laz;
}T[N * + ];
LL a[N];
void pushup(int p)
{
T[p].sum = T[p * ].sum + T[p * + ].sum;
if (T[p * ].laz == T[p * + ].laz)
T[p].laz = T[p * ].laz;
else
T[p].laz = ;
}
void pushdown(int p)
{
if (T[p].laz)
{
T[p * ].laz = T[p * + ].laz = T[p].laz;
T[p * ].sum = T[p].laz * (T[p * ].r - T[p * ].l + );
T[p * + ].sum = T[p].laz * (T[p * + ].r - T[p * + ].l + );
}
}
void update1(int x, int l, int r)
{
if (T[x].laz&&T[x].l == l&&T[x].r == r)
{
T[x].laz = euler[T[x].laz];
T[x].sum = T[x].laz * (T[x].r - T[x].l + );
return;
}
pushdown(x);
int mid = (T[x].l + T[x].r) / ;
if (r <= mid)
update1(x * , l, r);
else if(l > mid)
update1(x * + , l , r);
else
{
update1(x * , l, mid);
update1(x * + , mid + , r);
}
pushup(x);
}
void update2(int x, int l, int r, LL val)
{
if (l == T[x].l&&r == T[x].r)
{
T[x].laz = val;
T[x].sum = (T[x].r - T[x].l + )*T[x].laz;
return;
}
pushdown(x);
int mid = (T[x].l + T[x].r) / ;
if (r <= mid)
update2(x * , l, r, val);
else if (l > mid)
update2(x * + , l, r, val);
else
{
update2(x * , l, mid, val);
update2(x * + , mid + , r, val);
}
pushup(x);
} void build(int x, int l, int r)
{
T[x].l = l, T[x].r = r;
T[x].laz = T[x].sum = ;
if (l == r)
{
T[x].laz = T[x].sum = a[l];
return;
}
int mid = (l + r) / ;
build(x * , l, mid);
build(x * + , mid + , r);
pushup(x);
} LL query(int x, int l, int r)
{
if (T[x].l == l&&T[x].r == r)
return T[x].sum;
int mid = (T[x].l + T[x].r) / ;
pushdown(x);
if (r <= mid)
return query(x * , l, r);
else if (l > mid)
return query(x * + , l, r);
else
return query(x * , l, mid) + query(x * + , mid + , r);
}
int t, n, m;
int main()
{
geteuler();
ios::sync_with_stdio();
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%lld", &a[i]);
build(, , n);
int op, L, R;
LL tmp;
while (m--)
{
scanf("%d%d%d", &op, &L, &R);
if (op == )
{
update1(, L, R);
}
else if (op == )
{
scanf("%lld", &tmp);
update2(, L, R, tmp);
}
else if (op == )
{
printf("%lld\n", query(, L, R));
}
}
}
}
Count Color
修改节点的值,查询区间总和
这里laz就表示当前区间元素是否相同 pushdown 顺推
pushup
只有当左右两边都是整块而且左右边的颜色相等才能设置laz =
这里多了一个左右都是整块的条件是因为在欧拉的题目中laz>0就表示是整块了 Rikka with Phi
laz有两个含义:laz== 表示当前区间多个元素值不同
laz == x 表示当前区间元素的值都是x
修改节点的值,查询区间总和
pushdown
顺推即可,laz 相同, sum计算一下
pushup
当前sum = 子区间sum之和
当前laz = 子区间laz 相同? 子区间laz,否则为0 分为块状区域统一处理,当处理比当前块更小的块的时候,把之前积累的信息传递下去,递归处理 两个题的区别在于颜色的题目不需要Laz来表示当前值,当前值用color表示即可 PUSHDOWN
更新结点数据
PUSHUP
根据结点更新当前点的数据
Rikka with Phi 线段树的更多相关文章
- HDU5634 Rikka with Phi 线段树
// HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...
- HDU 5634 Rikka with Phi 线段树
题意:bc round 73 div1 D 中文题面 分析:注意到10^7之内的数最多phi O(log(n))次就会变成1, 因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护. 每次求p ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- HDU 6089 Rikka with Terrorist (线段树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...
- Rikka with Mista 线段树求交点个数
由于上下线段是不可能有交点的 可以先看左右线段树,按照y递增的顺序,对点进行排序. 升序构造,那么对于从某一点往下的射线,对于L,R进行区间覆盖,线段交点个数就是单点的被覆盖的次数. 降序构造,那么对 ...
- HDU5828 Rikka with Sequence 线段树
分析:这个题和bc round 73应该是差不多的题,当时是zimpha巨出的,那个是取phi,这个是开根 吐槽:赛场上写的时候直接维护数值相同的区间,然后1A,结果赛后糖教一组数据给hack了,仰慕 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- 牛客多校第十场 A Rikka with Lowbit 线段树
链接:https://www.nowcoder.com/acm/contest/148/A来源:牛客网 题目描述 Today, Rikka is going to learn how to use B ...
随机推荐
- AJPFX分析int 和integer的区别
int是java提供的8种原始数据类型之一.Java为每个原始类型提供了封装类,Integer是java为int提供的封装类.int的默认值为0,而Integer的默认值为null,即Integer可 ...
- dotnet cors 跨域问题
研究了一整子的.net core框架,感觉挺好用的,可以用在实际项目中,前端avalon框架也在研究: 问题:跨域,相比原来的跨域解决方案,还是有不小的变化的,原来的.net api 只需要在WebA ...
- java 线程池第一篇 之 ThreadPoolExcutor
一:什么是线程池? java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理.当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程.减少系统资源的 ...
- 打包Scala jar 包的正确步骤
实验目的:打包可运行的scala jar,上传到spark集群,提交执行 1.idea中编译运行代码,可成功运行 2.修改2处代码//只配置appName,其他配置项注释掉val conf=new S ...
- SQL Server性能调优——报表数据库与业务数据库分离
前段时间把公司的主数据库切了,分成业务库和报表库,业务库向报表库进行实时的Replication.这个项目的上线提升了系统的性能和可维护性,现在把设计时的考量和所做的工作重新回顾一下,作为备忘. 项目 ...
- cksum - 一个文件的检查和以及字节数
SYNOPSIS(总览) ../src/cksum [OPTION]... [FILE]... DESCRIPTION(描述) 输出CRC(循环冗余校验码)检查和以及每个FILE的字节数. --hel ...
- 用cesium本身添加水纹效果
参考网站:https://blog.csdn.net/XLSMN/article/details/78752669 1.首先来看一下整体效果 2.具体方法如下: 首先,你必须有两张很重要的图片,你可以 ...
- 0.ssm web项目中的遇到的坑
1.自定义的菜单,href为项目的相对路径,即: : 点击一个菜单,后再点击另一个菜单,然后发现浏览器地址栏的链接是在上一个链接后面拼接的,也就报错了. 解决办法: 每一个菜单的href前增加&quo ...
- SpringBoot 全局处理以及注入请求参数
后端接口,经常会用token获取对应的账号信息.于是考虑将这个步骤封装起来. 之前项目使用ThreadLocal去做这样的事情,但昨天看SpringBoot的官方文档,发现借助框架的功能也可以做这样的 ...
- 动态 SQL(1)
使用动态 SQL 完成多条件查询 动态 SQL 是 MyBatis 的一个强大的特性.在使用 JDBC 操作数据时,如果查询条件特别多,将条件串联成 SQL 字符串是一件痛苦的事情,通常的解决方法是写 ...