Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国
题目大意:
一个数列 支持两种操作
1 把区间内的数变成他们自己的约数个数
2 求区间和
思路:
可以想到每个数最终都会变成2或1
然后我们可以线段树
修改的时候记录一下每段有没有全被修改成1或2 是的话就不修改了
不是就暴力修改 因为每个数被修改的次数很小
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 1001000
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,g[MAXN],cnt[MAXN],m;
struct data{ll sum,mx;}tr[MAXN<<];
inline void pshp(int k)
{
tr[k].sum=tr[k<<].sum+tr[k<<|].sum;
tr[k].mx=max(tr[k<<].mx,tr[k<<|].mx);
}
void build(int k,int l,int r)
{
if(l==r) {tr[k].sum=tr[k].mx=g[l];return ;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
pshp(k);
}
inline ll query(int k,int a,int b,int l,int r)
{
if(l==a&&r==b) return tr[k].sum;
int mid=(l+r)>>;
if(mid>=b) return query(k<<,a,b,l,mid);
else if(mid<a) return query(k<<|,a,b,mid+,r);
else return query(k<<,a,mid,l,mid)+query(k<<|,mid+,b,mid+,r);
}
inline void upd(int k,int a,int b,int l,int r)
{
if(tr[k].mx<=) return ;
if(l==r) {tr[k].sum=tr[k].mx=cnt[tr[k].mx];return ;}
int mid=(l+r)>>;
if(mid>=b) upd(k<<,a,b,l,mid);
else if(mid<a) upd(k<<|,a,b,mid+,r);
else {upd(k<<,a,mid,l,mid);upd(k<<|,mid+,b,mid+,r);}
pshp(k);
}
int main()
{
int a,b,c;
for(int i=;i<=MAXN;i++)
for(int j=i;j<=MAXN;j+=i) cnt[j]++;
n=read(),m=read();
for(int i=;i<=n;i++) g[i]=read();
build(,,n);
while(m--)
{
a=read(),b=read(),c=read();
if(a==) upd(,b,c,,n);
else printf("%I64d\n",query(,b,c,,n));
}
}
UPD:
bzoj 3211 区间开根号 思路同上
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 2139062143
#define ll long long
#define MAXN 100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,g[MAXN],m;
struct data{ll sum,mx;}tr[MAXN<<];
inline void pshp(int k)
{
tr[k].sum=tr[k<<].sum+tr[k<<|].sum;
tr[k].mx=max(tr[k<<].mx,tr[k<<|].mx);
}
void build(int k,int l,int r)
{
if(l==r) {tr[k].sum=tr[k].mx=g[l];return ;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
pshp(k);
}
inline ll query(int k,int a,int b,int l,int r)
{
if(l==a&&r==b) return tr[k].sum;
int mid=(l+r)>>;
if(mid>=b) return query(k<<,a,b,l,mid);
else if(mid<a) return query(k<<|,a,b,mid+,r);
else return query(k<<,a,mid,l,mid)+query(k<<|,mid+,b,mid+,r);
}
inline void upd(int k,int a,int b,int l,int r)
{
if(tr[k].mx<=) return ;
if(l==r) {tr[k].sum=tr[k].mx=sqrt(tr[k].sum);return ;}
int mid=(l+r)>>;
if(mid>=b) upd(k<<,a,b,l,mid);
else if(mid<a) upd(k<<|,a,b,mid+,r);
else {upd(k<<,a,mid,l,mid);upd(k<<|,mid+,b,mid+,r);}
pshp(k);
}
int main()
{
int a,b,c;
n=read();
for(int i=;i<=n;i++) g[i]=read();
m=read();
build(,,n);
while(m--)
{
a=read(),b=read(),c=read();
if(a==) upd(,b,c,,n);
else printf("%lld\n",query(,b,c,,n));
}
}
Codeforces 920F. SUM and REPLACE / bzoj 3211 花神游历各国的更多相关文章
- BZOJ 3211: 花神游历各国( 线段树 )
线段树...区间开方...明显是要处理到叶节点的 之前在CF做过道区间取模...差不多, 只有开方, 那么每个数开方次数也是有限的(0,1时就会停止), 最大的数10^9开方10+次也就不会动了.那么 ...
- BZOJ 3211: 花神游历各国【线段树区间开方问题】
3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 3514 Solved: 1306[Submit][Status][Discu ...
- BZOJ 3038: 上帝造题的七分钟2 / BZOJ 3211: 花神游历各国 (线段树区间开平方)
题意 给出一些数,有两种操作.(1)将区间内每一个数开方(2)查询每一段区间的和 分析 普通的线段树保留修改+开方优化.可以知道当一个数为0或1时,无论开方几次,答案仍然相同.所以设置flag=1变表 ...
- BZOJ 3211 花神游历各国 线段树平方开根
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3211 题目大意: 思路: 由于数据范围只有1e9,一个数字x开根号次数超过logx之后 ...
- bzoj 3211: 花神游历各国
#include<cstdio> #include<cmath> #include<iostream> #define M 100006 using namespa ...
- BZOJ 3211 花神游历各国 (树状数组+并查集)
题解:首先,单点修改求区间和可以用树状数组实现,因为开平方很耗时间,所以在这个方面可以优化,我们知道,开平方开几次之后数字就会等于1 ,所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字 ...
- Codeforces 920F - SUM and REPLACE
920F - SUM and REPLACE 思路1: 线段树(982 ms) 每个点最多更新6次 代码: #include<bits/stdc++.h> using namespace ...
- Codeforces 920F - SUM and REPLACE 【线段树】
<题目链接> 题目大意: 给你一个序列,有两个操作,一个是求区间 l - r 的和,另一个是对区间l-r的元素修改值,x=d(x),d(x)为x的因子个数. 解题分析: 因为可能有多次修改 ...
- 2018.12.15 codeforces 920F. SUM and REPLACE(线段树)
传送门 线段树入门题. 给你一个序列:支持区间修改成自己的约数个数,区间求和. 实际上跟区间开方一个道理. 2的约数个数为2,1的约数个数为1,因此只要区间的最大值小于3就不用修改否则就暴力修改. 因 ...
随机推荐
- 梦想CAD控件关于比较问题
全图比较 怎么比较两个CAD图纸文件修改前后的不同部分呢?在工程图纸设计中,我们更多情况下可能需要对同一张工程图的前后修改部分进行对比,以确定工程图纸的改动部分及追溯原因,本教程演示了几种常见的比较方 ...
- ThinkPHP---TP功能类之联表查询
[一]介绍 在原生的sql中使用join 语法进行数据的联表查询, 在ThinkPHP里支持联表查询操作,但是可以归纳成两种方式:table方法.join方法 (1)table方法:在TP中对应SQL ...
- 配置redis三主三从
主从环境 centos7.6 redis4.0.1 主 从 192.168.181.139:6379 192.168.181.136:6379 192.168.181.136:6380 192.168 ...
- XGBoost参数中文翻译以及参数调优
XGBoost:参数解释:https://blog.csdn.net/zc02051126/article/details/46711047 机器学习系列(11)_Python中Gradient Bo ...
- 代码静态分析工具-splint的学习与使用[转]
代码静态分析工具--splint的学习与使用[转] 引言 最近在项目中使用了静态程序分析工具PC-Lint,体会到它在项目实施中带给开发人员的方便.PC-Lint是一款针对C/C++语言.window ...
- canvas练手项目(三)——Canvas中的Text文本
Canvas中的Text文本也是一个知识点~,我们需要掌握一下几个基本的Text操作方法 首先是重要参数textAlign和textBaseline: textAlign left center ri ...
- HTTP服务和APACHE2
HTTP服务和APACHE2 知识点 请求报文响应报文 错误码 请求重定向 编译安装 实现https curl工具 1. http协议 http协议版本 http/0.9, http/1.0, htt ...
- Linux iostat-监视系统输入输出设备和CPU的使用情况
推荐:更多linux 性能监测与优化 关注:linux命令大全 iostat命令被用于监视系统输入输出设备和CPU的使用情况.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同vmsta ...
- LINUX-网络 - (以太网和WIFI无线)
ifconfig eth0 显示一个以太网卡的配置 ifup eth0 启用一个 'eth0' 网络设备 ifdown eth0 禁用一个 'eth0' 网络设备 ifconfig eth0 192. ...
- LINUX-YUM 软件包升级器 - (Fedora, RedHat及类似系统)
yum install package_name 下载并安装一个rpm包 yum localinstall package_name.rpm 将安装一个rpm包,使用你自己的软件仓库为你解决所有依赖关 ...