题目链接: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 (线段树)的更多相关文章

  1. HDU 5634 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5634 题意:给定一个长度为n的序列,有m次操作.操作有3种: 1 l,r :区间[l,r]的值变成ph ...

  2. 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 ...

  3. hdu 3974 线段树 将树弄到区间上

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  5. hdu 3397 线段树双标记

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  6. hdu 4578 线段树(标记处理)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others) ...

  7. hdu 4533 线段树(问题转化+)

    威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  8. hdu 2871 线段树(各种操作)

    Memory Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  9. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  10. hdu 1542 线段树扫描(面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. HTTP请求方法:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE 说明

    平时的Rest开发,用到的都是GET,POST,PUT,DELETE类型的请求. 但Rest支持的请求类型不止前面4种,还有其他几种. 下面部分转自: https://www.html.cn/arch ...

  2. Servlet的request和response

    SERVLET API中forward() 与redirect()的区别?  答:前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址:后者则是完全的跳转,浏览器将会得到跳转的地址 ...

  3. java CGLib代理

    转载自   cglib之Enhancer 1. 背景 cglib库的Enhancer在Spring AOP中作为一种生成代理的方式被广泛使用.本文针对Enhancer的用法以实际代码为例作一些介绍. ...

  4. spark调优篇-spark on yarn web UI

    spark on yarn 的执行过程在 yarn RM 上无法直接查看,即 http://192.168.10.10:8088,这对于调试程序很不方便,所以需要手动配置 配置方法 1. 配置 spa ...

  5. pt-table-checksum和pt-table-sync使用

    pt-table-checksum和pt-table-sync使用 数据库版本:5.6.25 pt工具版本:2.2.14 主从关系一:不同机器同一端口 10.10.228.163:4306(rescs ...

  6. 利用element-ui封装地址输入的组件

    我们前端做项目时,难免会遇到地址输入,多数情况下,我们都是提供一个省市三级联动,加上具体地址输入的Input输入框给用户,用以获取用户需要输入的真实地址.在需要对用户输入的数据进行校验的时候,我们会单 ...

  7. Mybatis 多个参数传入的多种方法

    ist<XXXBean> getXXXBeanList(HashMap map); <select id="getXXXBeanList" parameterTy ...

  8. Vue大概知识体系和学习参考

    Vue大概知识体系和学习参考文档 官方文档学习,参考,借鉴地址:https://cn.vuejs.org/v2/guide/installation.html 菜鸟教程:https://www.run ...

  9. S5PV210 点亮Led

    GPC1CON, R/W, Address = 0xE020_0080 GPC1DAT, R/W, Address = 0xE020_0084 举例 #define GPC1CON *((volati ...

  10. 通过mysql 连接远程数据库时,输入密码后,提示10060错误

    能提示输入密码,说明网络能够连接,而且能连到服务器.输入密码后提示错误,说明应该是权限问题 解决方法: ​一.进入mysql数据库命令行 ​二.输入use mysql; ​三.设置root账号密码为1 ...