Codeforces 920F - SUM and REPLACE 【线段树】
<题目链接>
题目大意:
给你一个序列,有两个操作,一个是求区间 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 【线段树】的更多相关文章
- Codeforces 920F - SUM and REPLACE
920F - SUM and REPLACE 思路1: 线段树(982 ms) 每个点最多更新6次 代码: #include<bits/stdc++.h> using namespace ...
- 2018.12.15 codeforces 920F. SUM and REPLACE(线段树)
传送门 线段树入门题. 给你一个序列:支持区间修改成自己的约数个数,区间求和. 实际上跟区间开方一个道理. 2的约数个数为2,1的约数个数为1,因此只要区间的最大值小于3就不用修改否则就暴力修改. 因 ...
- CodeForces - 920F SUM and REPLACE (线段树)
题意:给N个数M次操作,(1<=N,M<=3e5, 1<=ai<=1e6),1是使[L,R]中的每个元素变成其因子的个数之和:2是求[L,R]区间之和 分析:看上去就很线段树的 ...
- 【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) ...
- Codeforces 85D Sum of Medians(线段树)
题目链接:Codeforces 85D - Sum of Medians 题目大意:N个操作,add x:向集合中加入x:del x:删除集合中的x:sum:将集合排序后,将集合中全部下标i % 5 ...
- Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国
题目大意: 一个数列 支持两种操作 1 把区间内的数变成他们自己的约数个数 2 求区间和 思路: 可以想到每个数最终都会变成2或1 然后我们可以线段树 修改的时候记录一下每段有没有全被修改成1或2 是 ...
- CF920F SUM and REPLACE 线段树
给你一个数组a_i,D(x)为x的约数个数 两种操作: 1.将[l,r]的a_i替换为D(a_i) 2.输出∑a_i ( l <= i <= r ) 当区间最大值<=2时,就不 ...
- codeforces 1217E E. Sum Queries? (线段树
codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...
- codeforces Good bye 2016 E 线段树维护dp区间合并
codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...
随机推荐
- jenkins自动发布java代码
注:本文来源于<KaliArch> jenkins笔记 一.相关概念 1.1 Jenkins概念: Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台. ...
- js获取url参数值,并解决中文乱码
<script type="text/javascript"> function GetQueryString(name) { var reg = new RegExp ...
- django----利用Form 实现两次密码输入是否一样 ( 局部钩子和全局钩子 )
from django import forms # 导入表单模块 from django.core.exceptions import ValidationError class RegisterF ...
- Nginx详解二十七:Nginx架构篇之安全篇
1.常见的恶意行为:爬虫行为和恶意抓取.资源盗用 解决方案: 基础防盗链功能:不让恶意用户能轻易爬去网站对外数据 secure_link_module模块:对数据安全性提高,加密验证和失效性,适合核心 ...
- ajax---异步请求对象的属性和方法
方法: 1).open(method.url,asyn):创建请求,(post.get)asyn:表示同步(false)还是异步(true)提交 ,默认true 2)send(body) 发送请求,b ...
- appium获取APP控件信息
uiautomatorviewer.bat 该文件位于SDK安装目录tools下,如笔者在“C:\Program Files (x86)\Android\android-sdk\tools”下,双击u ...
- 创建Python虚拟环境
以window为例: 安装完python后, 打开cmd, 命令行输入: pip install virtualenv ,安装过程见截图 进入你想安装虚拟环境的目录, 命令行输入: virtualen ...
- python pop方法
在两个地方见到了pop方法的使用,看起来是之前自己确实故略寡闻了. 在pandas的DataFrame中 import pandas as pd dataframe = pd.read_csv('ir ...
- 迅速上手:使用taro构建微信小程序基础教程
前言 由于微信小程序在开发上不能安装npm依赖,和开发流程上也饱受诟病:Taro 是由京东·凹凸实验室(aotu.io)倾力打造的 多端开发解决方案,它的api基于react,在本篇文章中主要介绍了使 ...
- TFS: 解决The build agent error - the session for this agent already exists
来源:http://ericphan.net/blog/2016/6/10/solving-the-tfs-build-agent-error-the-session-for-this-agent-a ...