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 ...
随机推荐
- validate[.unobtrusive]和Bootstrap实现tooltip错误提示
validate[.unobtrusive]和Bootstrap实现tooltip错误提示 类似的文章园子里已有,请看这里,个人感觉稍显复杂,日前也打算写一个简单的给项目用,一些关键点记录于此.最终效 ...
- maven3.1.1适合搭配的jdk版本
maven 可以帮助我们管理项目的jar 不同的版本对jdk的要求也不相同, 比如3.1.1就要搭配1.6或以上的jre但是1.7有的版本还是会有点问题 当maven所需的jre版本不对应时项目会报错 ...
- net use命令详细解释
1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接: net use \ ...
- TWaver3D入门探索——3D拓扑图之人在江湖
俗话说,有人的地方就有江湖,江湖就是帮派林立错综复杂的关系网.今天我们就来展示这样一个小小的江湖. 故事背景 崇祯末年,民不聊生,烽烟四起-- 江湖都是有背景的,我们的3D江湖也需要一个背景.江湖就是 ...
- 使用 Android Studio 跑新浪微博SDK Demo遇到的问题及解决
概述 这是新浪微博官方 Android SDK Demo 使用 Android Studio 导入.编译并运行通过的版本. 源码:WeiboSdkDemo 官方项目请点击: weibo_android ...
- js 人工获取年月日
var date = new Date(); var months = new Array("01", "02", "03", " ...
- Searching in a rotated and sorted array
Given a sorted array that has been rotated serveral times. Write code to find an element in this arr ...
- JSON用法简介
[JSON简介] jsoncpp 主要包含三种类型的 class:Value.Reader.Writer.jsoncpp 中所有对象.类名都在 namespace Json 中,包含 json.h 即 ...
- 如何在DJANGO里获取?带数据的东东,基于CBV
用DEF的,有现成的,而用CLASS的,就要作一下变通. 如下: if self.request.GET: if self.request.GET.get('search_pk'): search_p ...
- spring 异常管理机制
三.异常处理的几种实现: 3.1.在经典的三层架构模型中,通常都是这样来进行异常处理的: A.持久层一般抛出的是RuntiomeException类型的异常,一般不处理,直接向上抛出. B.业务层一般 ...