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 ...
随机推荐
- mysql导入问题
今天在导入数据库的时候,发现此问题: 后来一查,是因为GTID_EXECUTED有值,而导出的文件中包含了SET @@GLOBAL.GTID_PURGED的操作,所以导入报错. 我们有两种方法解决 ...
- POJ3311 Hie with the Pie 【状压dp/TSP问题】
题目链接:http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total ...
- 搭建Leanote笔记
mongo\leanote #查询Linux开放的端口 netstat -nupl (UDP类型的端口) netstat -ntpl (TCP类型的端口) #下载安装MongoDB wget http ...
- 【LOJ】#3051. 「十二省联考 2019」皮配
LOJ#3051. 「十二省联考 2019」皮配 当时我在考场上觉得这题很不可做... 当然,出了考场后再做,我还是没发现学校和城市是可以分开的,导致我还是不会 事实上,若一个城市投靠了某个阵营,学校 ...
- opencv实现人脸识别(四) 人脸识别模块
到这一步就是进行人脸识别了. 流程图: 代码: import cv2 def recognize(cam): recognizer = cv2.face.LBPHFaceRecognizer_crea ...
- Angular 表单验证类库 ngx-validator 1.0 正式发布
背景介绍 之前写了一篇 <如何优雅的使用 Angular 表单验证>,结尾处介绍了统一验证反馈的类库 ngx-validator ,由于这段时间一直在新模块做微前端以及相关业务组件库, ...
- 以前面试 经常写这种 问掉的 copy 还是 =
get的时候,生成的 那个对象赋值给aa 生成的对象在这条语句完 就析构了: https://blog.csdn.net/qq_31759205/article/details/80544468h ...
- 谈谈对Spring IOC的理解(转发)
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...
- SQL生成自动序号 带有占位符(掩码),可以调整占位长度的语句
MSSQL 语句 --声明变量 DECLARE @i int DECLARE @xh varchar(10) DECLARE @name varchar(10) Set @i = 0 --开始循环插入 ...
- Windows 软件使用
1.CMD 1. 查看端口对应进程 netstat -ano|findstr "443" 2.通过PID 查找对应进程 tasklist|findstr “<PID号> ...