HDU 5634 (线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634
题意:给出 n 个数,有三种操作,把区间的 ai 变为 φ(ai);把区间的 ai 变为 x;查询区间和。
题解:因为一个数由 ai 变为 φ(ai)在 log 次之后会变为 1 并且一直都为 1,考虑在没有第二种操作的情况下,只需要暴力修改记录区间最大值是否大于 1 即可。在加入第二个操作之后,可以发现对区间进行修改的话,一个区间内的数都是相同的,进行第一个操作可以对整个区间进行操作,故可以用线段树多记录一个区间内的数是否相同即可。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int MAXN = 3e5 + ;
const int MAXM = 1e7 + ;
const ll mod = 1e9 + ; bool check[MAXM];
int phi[MAXM], prime[MAXM / ], tot; void init(int N) {
tot = ;
phi[] = ;
for(int i = ; i <= N; i++) {
if(!check[i]) {
prime[tot++] = i;
phi[i] = i - ;
}
for(int j = ; j < tot; j++) {
if(i * prime[j] > N) break;
check[i * prime[j]] = true;
if(i % prime[j] == ) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
} else phi[i * prime[j]] = phi[i] * (prime[j] - );
}
}
} int a[MAXN],num[MAXN<<];
ll sum[MAXN<<]; void pushup(int rt) {
sum[rt] = sum[rt<<] + sum[rt<<|];
if(num[rt<<] == num[rt<<|]) num[rt] = num[rt<<];
else num[rt] = ;
// num[rt] = (num[rt<<1] == num[rt<<1|1]) ? num[rt] : 0;
} void build(int rt,int l,int r) {
if(l == r) {
sum[rt] = num[rt] = a[l];
return ;
}
int mid = (l + r) >> ;
build(rt<<,l,mid);
build(rt<<|,mid + ,r);
pushup(rt);
} void pushdown(int rt,int l,int r) {
if(num[rt]) {
int mid = (l + r) >> ;
num[rt<<] = num[rt<<|] = num[rt];
sum[rt<<] = 1ll * num[rt<<] * (mid - l + );
sum[rt<<|] = 1ll * num[rt<<|] * (r - mid);
num[rt] = ;
}
} void update1(int rt,int l,int r,int ql,int qr) {
if(ql > qr) return ;
if(num[rt] && l == ql && r == qr) {
num[rt] = phi[num[rt]];
sum[rt] = 1ll * num[rt] * (r - l + );
return ;
}
pushdown(rt,l,r);
int mid = (l + r) >> ;
if(qr <= mid) update1(rt<<,l,mid,ql,qr);
else if(ql > mid) update1(rt<<|,mid + ,r,ql,qr);
else {
update1(rt<<,l,mid,ql,mid);
update1(rt<<|,mid + ,r,mid + ,qr);
}
pushup(rt);
} void update2(int rt,int l,int r,int ql,int qr,int val) {
if(ql > qr) return ;
if(l == ql && r == qr) {
num[rt] = val;
sum[rt] = 1ll * num[rt] * (r - l + );
return ;
}
pushdown(rt,l,r);
int mid = (l + r) >> ;
if(qr <= mid) update2(rt<<,l,mid,ql,qr,val);
else if(ql > mid) update2(rt<<|,mid + ,r,ql,qr,val);
else {
update2(rt<<,l,mid,ql,mid,val);
update2(rt<<|,mid + ,r,mid + ,qr,val);
}
pushup(rt);
} ll query(int rt,int l,int r,int ql,int qr) {
if(ql == l && qr == r) return sum[rt];
pushdown(rt,l,r);
int mid = (l + r) >> ;
if(qr <= mid) return query(rt<<,l,mid,ql,qr);
else if(ql > mid) return query(rt<<|,mid + ,r,ql,qr);
else return query(rt<<,l,mid,ql,mid) + query(rt<<|,mid + ,r,mid + ,qr);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
init(1e7);
int t;
scanf("%d",&t);
while(t--) {
int n,m;
scanf("%d%d",&n,&m);
for(int i = ; i <= n; i++) scanf("%d",&a[i]);
build(,,n);
while(m--) {
int op,l,r,x;
scanf("%d",&op);
if(op == ) {
scanf("%d%d",&l,&r);
update1(,,n,l,r);
} else if(op == ) {
scanf("%d%d%d",&l,&r,&x);
update2(,,n,l,r,x);
} else if(op == ) {
scanf("%d%d",&l,&r);
printf("%lld\n",query(,,n,l,r));
}
}
}
return ;
}
HDU 5634 (线段树)的更多相关文章
- HDU 5634 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 题意:给定一个长度为n的序列,有m次操作.操作有3种: 1 l,r :区间[l,r]的值变成ph ...
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4533 线段树(问题转化+)
威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- hdu 2871 线段树(各种操作)
Memory Control Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 4052 线段树扫描线、奇特处理
Adding New Machine Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- [Arc102B]All Your Paths are Different Lengths_构造_二进制拆分
All Your Paths are Different Lengths 题目链接:https://atcoder.jp/contests/arc102/tasks/arc102_b 题解: 构造题有 ...
- springboot @vaule注解失效解决办法
在Controller类里面通过@Value将参数注入进来,最后的确成功了.因此基于此经验,我便在其他使用的类里面也采用这样的方式注入参数,但是发现去失效了,报错为NULL,说明参数并没有我们料想的被 ...
- Spring4学习回顾之路11-AOP
Srping的核心除了之前讲到的IOC/DI之外,还有一个AOP(Aspect Oriented Programming:面向切面编程):通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 ...
- MySQL 按照日期格式查询带有时间戳数据
按照日期格式查询带有时间戳数据一般在MSQL数据库中的时间都是以时间戳的格式来存储时间的,但是对于我们来说,时间戳格式具体表示的是什么时间,我们很难一眼看出来,所以当我们要具体查询某一个时间或时间段的 ...
- S03_CH02_AXI_DMA PL发送数据到PS
S03_CH02_AXI_DMA PL发送数据到PS 1.1概述 本课程的设计原理分析. 本课程循序渐进,承接<S03_CH01_AXI_DMA_LOOP 环路测试>这一课程,在DATA ...
- getContextPath、getServletPath、getRequestURI、getRealPath、getRequestURL、getPathInfo();的区别
<% out.println("getContextPath: "+request.getContextPath()+"<br/>"); ou ...
- 怎样安装并编译TypeScript?
1. 使用: npm -v 查看是否安装了 npm , 如果没有安装, 请前往 Nodejs 官网 下载安装, 下图表示已经安装 npm , 版本为: 6.9.0 . PS C:\Users\Adm ...
- SIP中的SDP offer/answer交换初探
1.引言 SDP的offer/answer模型本身独立与于利用它的高层协议.SIP是使用offer/answer模型的应用之一.RFC 3264 定义了offer/answer模型,但没有规定使用哪个 ...
- 记录一次SourceTree无法push问题排查及解决
1.push代码卡住,一直转圈2.试了下拉取代码也拉不到3.试了使用git命令行push可以4.使用Sourcetree新建项目,一直在检查url.5.初步判断原因,SourceTree无法联网.6. ...
- h5学习之表单
<html> <head> <title>新型input类型及表单新元素</title> <meta charset="utf-8&qu ...