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 ...
随机推荐
- Java编程思想(三)控制程序流程
3.1.10逗号运算符 我们可以使用一系列由逗号分隔的语句,而且哪些语句均会独立执行. 3.1.15复习计算顺序
- [转帖]tr命令的用法
tr命令的用法 https://www.cnblogs.com/bingguoguo/articles/9188703.html tr命令 tr命令可以对来自标准输入的字符进行替换.压缩和删除.它 ...
- [转帖]Linux systemd 常用命令
Linux systemd 常用命令 https://www.cnblogs.com/tsdxdx/p/7288490.html systemctl hostnamectl timedatectl l ...
- 浅谈>/dev/null 2>&1
在crond计划任务.nohup中我们经常可以看到>/dev/null 2>&1,但是很多人并不理解其含义,想要真正的理解它,首先我们需要知道文件描述符的三种类型. 类型 文件描述 ...
- fiddler模拟发送请求和响应
iddler模拟发送请求和响应 一.fiddler模拟发送请求 1.fiddler模拟发送get请求 1)例如:访问博客园https://www.cnblogs.com/,并且登录输入密码账号登录,再 ...
- redis集群(多机)分布
一.实现原理 一致性哈希算法(Consistent Hashing): http://www.zsythink.net/archives/1182 二.配置两个redis服务,端口号要不一致 三.代码 ...
- 3-MySQL DBA笔记-开发基础
第二部分 开发篇 本篇首先讲述数据库开发的一些基础知识,如关系数据模型.常用的SQL语法.范式.索引.事务等,然后介绍编程开发将会涉及的数据库的一些技巧,最后结合生产实际,提供一份开发规范供大家参考. ...
- c#连接数据库SqlHelper报错
这是一个困扰了我好几天的问题,首先看一下报错信息 代码: private static string connectionString = ConfigurationManager.Connectio ...
- c#将电脑时间同步到网络时间
最近遇到个项目,需要控制软件使用时间,由于电脑不联网可以修改时间,故需要联网使电脑同步网络时间 网上寻找了很多解决方案,代码如下: //Forproc_Win32.cs//对常用Win32 API函数 ...
- intellij IDE 破解 简单 License server 法
http://idea.iteblog.com/key.php