HDU 5634 Rikka with Phi 线段树
题意:bc round 73 div1 D 中文题面
分析:注意到10^7之内的数最多phi O(log(n))次就会变成1,
因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护。
每次求phi的时候就在平衡树上取出这个区间然后暴力求phi,如果一段数变成了1,
就在平衡树里面删掉它,最后统计答案的时候只要把区间中被删去的1加回答案即可,
时间复杂度O((n + m)logn)
注:平衡树,写起来麻烦(然后其实我也不会写)
但是题解当中说把一段相同的数缩成一个点,就很好
所以用线段树,节点维护区间和以及(当这个区间元素都相同时)维护这个元素
然后操作2和操作3就是普通的线段树应用,区间更新以及区间求和
然后操作1,由于我维护了一整段相同元素的区间,所以更新时,
只要按照区间更新,区间在更新范围内,且节点所管辖区间的元素全部相同的时候,直接修改节点
区间更新就好了,这样的话,时间复杂度不是很高
由于单个元素的范围是1e7,所以先筛一遍欧拉函数
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e7;
const int maxn=3e5+;
const LL mod = 1e9+;
int phi[N+],n,m,T;
int o[maxn<<],mark[maxn<<];
LL sum[maxn<<];
void pushup(int rt)
{
sum[rt]=sum[rt*]+sum[rt*+];
if(o[rt*]==o[rt*+]&&o[rt*])
o[rt]=o[rt*];
else o[rt]=;
}
void pushdown(int rt,int l,int r)
{
if(mark[rt])
{
int mid=(l+r)>>;
sum[rt*]=1ll*(LL)(mid-l+)*(LL)(mark[rt]);
sum[rt*+]=1ll*(LL)(r-mid)*(LL)(mark[rt]);
o[rt*]=o[rt*+]=mark[rt];
mark[rt*]=mark[rt*+]=mark[rt];
mark[rt]=;
}
}
void build(int rt,int l,int r)
{
if(l==r)
{
scanf("%d",&o[rt]);
sum[rt]=o[rt];
return ;
}
int mid=(l+r)>>;
build(rt*,l,mid);
build(rt*+,mid+,r);
pushup(rt);
}
void op1(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y&&o[rt])
{
int tmp=phi[o[rt]];
o[rt]=mark[rt]=tmp;
sum[rt]=1ll*(LL)(r-l+)*(LL)(tmp);
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>;
if(x<=mid)op1(rt*,l,mid,x,y);
if(y>mid)op1(rt*+,mid+,r,x,y);
pushup(rt);
}
int t;
void op2(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
o[rt]=mark[rt]=t;
sum[rt]=1ll*(LL)(r-l+)*(LL)(t);
return;
}
pushdown(rt,l,r);
int mid=(l+r)>>;
if(x<=mid)op2(rt*,l,mid,x,y);
if(y>mid)op2(rt*+,mid+,r,x,y);
pushup(rt);
}
LL op3(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return sum[rt];
pushdown(rt,l,r);
int mid=(l+r)>>;
LL ans=;
if(x<=mid)ans+=op3(rt*,l,mid,x,y);
if(y>mid)ans+=op3(rt*+,mid+,r,x,y);
return ans;
}
int main()
{
phi[]=;
for(int i=; i<=N; ++i)
{
if(!phi[i])
{
for(int j=i; j<=N; j+=i)
{
if(!phi[j])
phi[j]=j;
phi[j]=phi[j]/i*(i-);
}
}
}
scanf("%d",&T);
while(T--)
{
memset(o,,sizeof(o));
memset(mark,,sizeof(mark));
scanf("%d%d",&n,&m);
build(,,n);
while(m--)
{
int c,l,r;
scanf("%d%d%d",&c,&l,&r);
if(c==)scanf("%d",&t);
if(c==)op1(,,n,l,r);
else if(c==)op2(,,n,l,r);
else printf("%I64d\n",op3(,,n,l,r));
}
}
return ;
}
HDU 5634 Rikka with Phi 线段树的更多相关文章
- HDU5634 Rikka with Phi 线段树
// HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...
- HDU 5634 Rikka with Phi
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 ------------------------------------------------ ...
- 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 Phi 线段树
Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
随机推荐
- C#和Js 编码和解码方法
Server.UrlDecode(); Server.UrlEncode(); Server.HtmlDecode(); Server.HtmlEncode();
- 关于安装Android Studio的一些问题的解决方法
问题1:每次Fetching android sdk component information 这是在检查你的 Android SDK .有人会在这里卡上很长时间,很大的原因就是:网络连接有问题.可 ...
- 2328: [HNOI2011]赛车游戏 - BZOJ
先把一定要减的费用先减掉,就是b*s*len(上坡路),下坡路就设一个初速度,使耗油为0,如果没油了,就无法到达 然后考虑加速 对于长度为len的路,增加v的速度需要len*a*v的油,与len成正比 ...
- [转载]mongoDB学习笔记——存取图片(C#)
作为一个NoSql数据库的代表,存取多媒体数据,应该是强项吧?那么,图片在mongoDB里是如何存取的呢?(其实,关系型数据库存取图片也一点问题没有,所以我看NoSql的强项不在于是否存储多媒体,而在 ...
- 对JAVA动态代理的理解
叫动态代理就代表着有“静态代理”这回事. 而且,通常“动态”至少听着更NB一点. 关键就在于不明白啥叫“动”,这个得跟“静”比较下. 在我的理解,静态代理得自己声明一个类,实现跟被代理对象同样的接口. ...
- 1028-Digital Roots
描述 The digital root of a positive integer is found by summing the digits of the integer. If the resu ...
- POJ3697+BFS+hash存边
/* 疾速优化+hash存边 题意:给定一个包含N(1 ≤ N ≤ 10,000)个顶点的无向完全图,图中的顶点从1到N依次标号.从这个图中去掉M(0 ≤ M ≤ 1,000,000)条边,求最后与顶 ...
- POJ2349+prim
最小生成树 /* prim 题意:给定一些点,一些卫星,一个卫星能连接两个点,点和点之间通信有一定的距离限制. 问能使得所有的点联通的最小距离. */ #include<stdio.h> ...
- 【形式化方法:VDM++系列】4.VDM实战1——铁路费用计算
又有将近2个月没更新博客了啊!winter holiday简直玩儿疯了的说!结果假期前学习的形式化方法已经忘了大半!面对期末作业,大脑一片空白.于是,赶快复习了一下之前学习的姿势! 这次的主要任务是完 ...
- Top命令内存占用剖析
原文: http://yalung929.blog.163.com/blog/static/203898225201212981731971/ 引 言: top命令作为Linux下最常用的性能分析工具 ...