题意: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 线段树的更多相关文章

  1. HDU5634 Rikka with Phi 线段树

    // HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...

  2. HDU 5634 Rikka with Phi

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 ------------------------------------------------ ...

  3. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  4. HDU 6089 Rikka with Terrorist (线段树)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=6089 题解 这波强行维护搞得我很懵逼... 扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左 ...

  5. Rikka with Phi 线段树

    Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...

  6. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  7. HDU 5828 Rikka with Sequence(线段树区间加开根求和)

    Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...

  8. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  9. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

随机推荐

  1. C#和Js 编码和解码方法

    Server.UrlDecode(); Server.UrlEncode(); Server.HtmlDecode(); Server.HtmlEncode();

  2. 关于安装Android Studio的一些问题的解决方法

    问题1:每次Fetching android sdk component information 这是在检查你的 Android SDK .有人会在这里卡上很长时间,很大的原因就是:网络连接有问题.可 ...

  3. 2328: [HNOI2011]赛车游戏 - BZOJ

    先把一定要减的费用先减掉,就是b*s*len(上坡路),下坡路就设一个初速度,使耗油为0,如果没油了,就无法到达 然后考虑加速 对于长度为len的路,增加v的速度需要len*a*v的油,与len成正比 ...

  4. [转载]mongoDB学习笔记——存取图片(C#)

    作为一个NoSql数据库的代表,存取多媒体数据,应该是强项吧?那么,图片在mongoDB里是如何存取的呢?(其实,关系型数据库存取图片也一点问题没有,所以我看NoSql的强项不在于是否存储多媒体,而在 ...

  5. 对JAVA动态代理的理解

    叫动态代理就代表着有“静态代理”这回事. 而且,通常“动态”至少听着更NB一点. 关键就在于不明白啥叫“动”,这个得跟“静”比较下. 在我的理解,静态代理得自己声明一个类,实现跟被代理对象同样的接口. ...

  6. 1028-Digital Roots

    描述 The digital root of a positive integer is found by summing the digits of the integer. If the resu ...

  7. POJ3697+BFS+hash存边

    /* 疾速优化+hash存边 题意:给定一个包含N(1 ≤ N ≤ 10,000)个顶点的无向完全图,图中的顶点从1到N依次标号.从这个图中去掉M(0 ≤ M ≤ 1,000,000)条边,求最后与顶 ...

  8. POJ2349+prim

    最小生成树 /* prim 题意:给定一些点,一些卫星,一个卫星能连接两个点,点和点之间通信有一定的距离限制. 问能使得所有的点联通的最小距离. */ #include<stdio.h> ...

  9. 【形式化方法:VDM++系列】4.VDM实战1——铁路费用计算

    又有将近2个月没更新博客了啊!winter holiday简直玩儿疯了的说!结果假期前学习的形式化方法已经忘了大半!面对期末作业,大脑一片空白.于是,赶快复习了一下之前学习的姿势! 这次的主要任务是完 ...

  10. Top命令内存占用剖析

    原文: http://yalung929.blog.163.com/blog/static/203898225201212981731971/ 引 言: top命令作为Linux下最常用的性能分析工具 ...