题意: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. linux驱动系列之ubuntu快捷键(转)

    Ubuntu快捷键-终端快捷键   1.关于终端的快捷键:    Tab:tab键是比较常用的一个快捷键,它的作用是补全文件名或者路径.举例 来说,输入”cd /ho”在按一下tab键,终端里就会显示 ...

  2. find 与 tar命令连用

    find 与 tar命令连用 今天打包日志时,用 -type f -exec tar -cvf log.tar {} \; 发现只打包了最后一个文件,应该是tar的c参数,每次都创建一个新的文件,想了 ...

  3. @Repository、@Service、@Controller 和 @Component(转)

    鸣谢:http://blog.csdn.net/ye1992/article/details/19971467 @Repository.@Service.@Controller 和 @Componen ...

  4. UIScrollView的坑--UINavigationController Push后位置变化

    今天在使用UIScrollView的时候遇到了一个问题,记录一下.如果这个记录有幸被您搜索到,或许对您有些帮助. 今天有这样一个需求: 在一个由导航条控制的页面中.需要显示一些信息,目前已经有10多行 ...

  5. ASP.NET MVC 数据分页思想及解决方案代码

    作为一个程序猿,数据分页是每个人都会遇到的问题.解决方案更是琳琅满目,花样百出.但基本的思想都是差不多的. 下面给大家分享一个简单的分页器,让初学者了解一下最简单的分页思想,以及在ASP.NET MV ...

  6. [转载]AOP面向方面编程

    1.引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创建和管理的模块.于是出现了以系统模块化特性的面向对象程序设计技术.模块化的面向对象编程极度极地提 ...

  7. 写作技巧--Simile明喻

  8. 团体程序设计天梯赛-练习集L1-005. 考试座位号

    L1-005. 考试座位号 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 每个PAT考生在参加考试时都会被分配两个座位号,一个 ...

  9. http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/

    http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/

  10. ZOJ 2563 Long Dominoes(状态压缩DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1563 题目大意:在h*w的矩阵里铺满1*3的小矩阵,共有多少种方法 ...