<题目链接>

题目大意:

给你一个序列,有两个操作,一个是求区间 l - r 的和,另一个是对区间l-r的元素修改值,x=d(x),d(x)为x的因子个数。

解题分析:

因为可能有多次修改操作,并且修改的范围可能比较大,所以提前将1~1e6范围内的数的因子个数全部打表进行处理。但是仅仅这样还是不行的,因为如果每次区间更新都暴力更新到叶子节点的话,区间更新 $O(nlog(n))$ ,然后m次询问,时间复杂度就达到了$O(n*mlog(n))$,而本题n给到了3e5,毫无疑问这样暴力更新是会超时的。我们发现1、2的因子数为它们本身,所以在更新的过程中,如果该区间都为1或2,就不用继续向下进行更新。

 #include <bits/stdc++.h>
using namespace std; #define N int(3e5+7)
#define Max int(1e6+7)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define clr(a,b) memset(a,b,sizeof(a))
#define rep(i,s,t) for(int i=s;i<=t;i++)
typedef long long ll;
int n,q;
int arr[N],facnum[Max+];
ll flag[N<<],tr[N<<]; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while(ch<''||ch>'')f|=(ch=='-'),ch=getchar();
while(ch>='' && ch<='')x=x*+ch-'',ch=getchar();
return x=f?-x:x;
}
int Getfac(int x){ //得到该数的所有因子数
int sum=,cnt;
for(int i=;i*i<=x;i++){
cnt=;
while(x%i==)x/=i,cnt++;
sum*=(cnt+);
}
if(x>) sum*=;
return sum;
}
void Pushup(int rt){
tr[rt]=tr[rt<<]+tr[rt<<|];
if(!flag[rt<<]&&!flag[rt<<|])flag[rt]=; //如果两个子区间都不需要修改,说明这个区间不需要再进行修改
}
void build(int rt,int l,int r){
flag[rt]=;
if(l==r){
tr[rt]=arr[l];return;
}
int mid=(l+r)>>;
build(lson);build(rson);
Pushup(rt);
}
void update(int rt,int l,int r,int L,int R){ //区间更新,维护一个区间标记,记录该区间是否需要改变
if(L<=l&&r<=R&&!flag[rt])return; //如果这部分区间不需要修改,直接返回
if(l==r){
tr[rt]=facnum[tr[rt]]; //进行单点修改
if(tr[rt]==||tr[rt]==)flag[rt]=; //如果该点为1或2,那么该点就不用再修改了,因为1、2的因子个数仍然为1、2
return;
}
int mid=(l+r)>>;
if(L<=mid&&flag[rt<<])update(lson,L,R);
if(R>mid&&flag[rt<<|])update(rson,L,R);
Pushup(rt);
}
ll query(int rt,int l,int r,int L,int R){ //区间查询
if(L<=l&&r<=R)return tr[rt];
ll ans=;
int mid=(l+r)>>;
if(L<=mid)ans+=query(lson,L,R);
if(R>mid)ans+=query(rson,L,R);
return ans;
}
int main(){
for(int i=;i<=Max;i++)facnum[i]=Getfac(i); //打表预处理得到1~1e6中所有的数的因子个数
read(n);read(q);
rep(i,,n)read(arr[i]);
build(,,n);
while(q--){
int op,x,y;
read(op);read(x);read(y);
if(op==)update(,,n,x,y);
else printf("%lld\n",query(,,n,x,y));
}
}

2019-02-16

Codeforces 920F - SUM and REPLACE 【线段树】的更多相关文章

  1. Codeforces 920F - SUM and REPLACE

    920F - SUM and REPLACE 思路1: 线段树(982 ms) 每个点最多更新6次 代码: #include<bits/stdc++.h> using namespace ...

  2. 2018.12.15 codeforces 920F. SUM and REPLACE(线段树)

    传送门 线段树入门题. 给你一个序列:支持区间修改成自己的约数个数,区间求和. 实际上跟区间开方一个道理. 2的约数个数为2,1的约数个数为1,因此只要区间的最大值小于3就不用修改否则就暴力修改. 因 ...

  3. CodeForces - 920F SUM and REPLACE (线段树)

    题意:给N个数M次操作,(1<=N,M<=3e5, 1<=ai<=1e6),1是使[L,R]中的每个元素变成其因子的个数之和:2是求[L,R]区间之和 分析:看上去就很线段树的 ...

  4. 【Educational Codeforces Round 37】F. SUM and REPLACE 线段树+线性筛

    题意 给定序列$a_n$,每次将$[L,R]$区间内的数$a_i$替换为$d(a_i)$,或者询问区间和 这题和区间开方有相同的操作 对于$a_i \in (1,10^6)$,$10$次$d(a_i) ...

  5. Codeforces 85D Sum of Medians(线段树)

    题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...

  6. Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国

    题目大意: 一个数列 支持两种操作 1 把区间内的数变成他们自己的约数个数 2 求区间和 思路: 可以想到每个数最终都会变成2或1 然后我们可以线段树 修改的时候记录一下每段有没有全被修改成1或2 是 ...

  7. CF920F SUM and REPLACE 线段树

    给你一个数组a_i​,D(x)为x的约数个数 两种操作: 1.将[l,r]的a_i​替换为D(a_i) 2.输出∑​a_i ( l <= i <= r ) 当区间最大值<=2时,就不 ...

  8. codeforces 1217E E. Sum Queries? (线段树

    codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...

  9. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

随机推荐

  1. fatal: refusing to merge unrelated histories

    Git 提交代码时遇到冲突了,所以 git pull 拉不下来远程代码.使用一下命令解决: git pull origin master --allow-unrelated-histories 然后解 ...

  2. 基于多进程的Tcp套接字服务器

    服务端 import socketfrom multiprocessing import Process def task(c): print('顾客吃点啥') while True: data = ...

  3. C++ 解析Json——jsoncpp(转)

    原文:https://www.cnblogs.com/liaocheng/p/4243731.html JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,和 ...

  4. Zookeeper安装(本地,伪分布式,集群)

    概述 ZooKeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization).命名服务(Namin ...

  5. 3790:最短路径问题(HDU)

    Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的.   Inp ...

  6. vue指令

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>指令 ...

  7. vue指令问题

    挂载点:最外层标签就是vue实例的挂载点,即id或者类对应的 dom节点 模板:指挂载点内部的内容,在实例里使用template标签来构 建 h1标签放在body里面不使用 “template”是一样 ...

  8. Spring-data-redis: serializer实例

    spring-data-redis提供了多种serializer策略,这对使用jedis的开发者而言,实在是非常便捷.sdr提供了4种内置的serializer: JdkSerializationRe ...

  9. XShell发送命令到全部会话

  10. LVS(IPVS)了解

    从来都只是看文章,现在手工作一下. 参考URL: https://blog.csdn.net/langyue919/article/details/80935197 https://www.cnblo ...