题意

给出一些数,有两种操作。(1)将区间内每一个数开方(2)查询每一段区间的和

分析

普通的线段树保留修改+开方优化。可以知道当一个数为0或1时,无论开方几次,答案仍然相同。所以设置flag=1变表示这一段区间全是0/1,那么修改的时候直接暴力遍历线段树结点。因为一个数被开方下取整到1,只会被开方几次,所以说这样修改是O(n)O(n)O(n)的.总时间还是O(nlogn)O(nlogn)O(nlogn)

CODE1

上帝造题的七分钟2

#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 100005;
int n, m;
struct seg {
LL sum; bool flg;
}t[MAXN<<2];
inline void upd(int i) {
t[i].sum = t[i<<1].sum + t[i<<1|1].sum;
t[i].flg = t[i<<1].flg & t[i<<1|1].flg;
}
void build(int i, int l, int r) {
t[i].flg = 0;
if(l == r) {
read(t[i].sum);
if(t[i].sum <= 1) t[i].flg = 1;
return;
}
int mid = (l + r) >> 1;
build(i<<1, l, mid);
build(i<<1|1, mid+1, r);
upd(i);
}
void modify(int i, int l, int r, int x, int y) {
if(t[i].flg) return;
if(l == r) {
t[i].sum = sqrt(t[i].sum);
if(t[i].sum <= 1) t[i].flg = 1;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) modify(i<<1, l, mid, x, y);
if(y > mid) modify(i<<1|1, mid+1, r, x, y);
upd(i);
}
LL query(int i, int l, int r, int x, int y) {
if(x <= l && r <= y) return t[i].sum;
int mid = (l + r) >> 1;
if(y <= mid) return query(i<<1, l, mid, x, y);
else if(x > mid) return query(i<<1|1, mid+1, r, x, y);
else return query(i<<1, l, mid, x, y) + query(i<<1|1, mid+1, r, x, y);
}
int main () {
read(n); build(1, 1, n); read(m);
int x, y, op;
while(m--) {
read(op), read(x), read(y);
if(x > y) swap(x, y); //坑!
if(!op) modify(1, 1, n, x, y);
else printf("%lld\n", query(1, 1, n, x, y));
}
}

CODE 2

花神游历各国

#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 100005;
int n, m;
struct seg {
LL sum; bool flg;
}t[MAXN<<2];
inline void upd(int i) {
t[i].sum = t[i<<1].sum + t[i<<1|1].sum;
t[i].flg = t[i<<1].flg & t[i<<1|1].flg;
}
void build(int i, int l, int r) {
t[i].flg = 0;
if(l == r) {
read(t[i].sum);
if(t[i].sum <= 1) t[i].flg = 1;
return;
}
int mid = (l + r) >> 1;
build(i<<1, l, mid);
build(i<<1|1, mid+1, r);
upd(i);
}
void modify(int i, int l, int r, int x, int y) {
if(t[i].flg) return;
if(l == r) {
t[i].sum = sqrt(t[i].sum);
if(t[i].sum <= 1) t[i].flg = 1;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) modify(i<<1, l, mid, x, y);
if(y > mid) modify(i<<1|1, mid+1, r, x, y);
upd(i);
}
LL query(int i, int l, int r, int x, int y) {
if(x <= l && r <= y) return t[i].sum;
int mid = (l + r) >> 1;
if(y <= mid) return query(i<<1, l, mid, x, y);
else if(x > mid) return query(i<<1|1, mid+1, r, x, y);
else return query(i<<1, l, mid, x, y) + query(i<<1|1, mid+1, r, x, y);
}
int main () {
read(n); build(1, 1, n); read(m);
int x, y, op;
while(m--) {
read(op), read(x), read(y);
if(op == 2) modify(1, 1, n, x, y);
else printf("%lld\n", query(1, 1, n, x, y));
}
}

BZOJ 3038: 上帝造题的七分钟2 / BZOJ 3211: 花神游历各国 (线段树区间开平方)的更多相关文章

  1. BZOJ 3038: 上帝造题的七分钟2

    3038: 上帝造题的七分钟2 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分 ...

  2. BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

    3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1469  Solved: 631[Submit][Status][Dis ...

  3. bzoj 3038: 上帝造题的七分钟2 线段树||hdu 4027

    3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 476[Submit][Status][Dis ...

  4. BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)

    题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> ...

  5. BZOJ 3038 上帝造题的七分钟2 树状数组+并查集

    题目大意:一个序列,有两种操作.1.将一段数中的每个数开根号.2.查询一段数的和. 思路:和3211是一个题,有兴趣的能够看看我的那篇博客. CODE: #include <cmath> ...

  6. BZOJ 3038 上帝造题的七分钟二

    无题目 但是百度会发现题目和3211基本一致 所以看上一篇博文的上一篇博文呢

  7. BZOJ 3211: 花神游历各国( 线段树 )

    线段树...区间开方...明显是要处理到叶节点的 之前在CF做过道区间取模...差不多, 只有开方, 那么每个数开方次数也是有限的(0,1时就会停止), 最大的数10^9开方10+次也就不会动了.那么 ...

  8. BZOJ 3211 花神游历各国 线段树平方开根

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3211 题目大意: 思路: 由于数据范围只有1e9,一个数字x开根号次数超过logx之后 ...

  9. 【BZOJ】3038: 上帝造题的七分钟2(线段树+暴力)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=3038 这题我就有得吐槽了,先是线段树更新写错,然后不知哪没pushup导致te,精度问题sq ...

随机推荐

  1. [TCP/IP] 滑动窗口

    什么是滑动窗口? 滑动窗口机制是TCP协议的一种流量控制和防拥塞的机制. 滑动窗口的工作原理? 简单来讲,就是接收方和发送方分别保留一块缓冲区,作为接收和发送数据来使用,发送数据过程中,如果发送方发的 ...

  2. [转帖]SPARC简介

    https://www.cnblogs.com/chaohm/p/5674886.html 1.    概述 SPARC(Scalable Processor ARChitecture,可扩展处理器架 ...

  3. tesseract 3.04在centos6上安装

    tesseract是一个开源的OCR文字识别工具 查找相关文章:tesseract   tesseract 4.0一直安装失败,后来参照网上的方法,成功安装3.04 1 2 3 4 5 6 7 8 9 ...

  4. dubbo分布式服务框架-study2

    本文开始对springboot+dubbo集成,使用的版本为springboot 2.0.0.dubbo 2.0.0,步骤如下: 1.添加依赖: <dependency> <grou ...

  5. Ural 1238 Folding 题解

    目录 Ural 1238 Folding 题解 题意 题解 程序 Ural 1238 Folding 题解 题意 定义折叠.展开为: 单个大写英文字母是一个折叠的串,把它展开后是它本身. 如果\(S\ ...

  6. PHP max_input_var设为了1000导致post数组太多时无法接受后面的参数值

    PHP max_input_var设为了1000导致post数组太多时无法接受后面的参数值 下午突然接到格力电话说无法批量设置门店任务,但是在测试环境下无法重现,测试环境下好好的. 然后登陆到生产环境 ...

  7. python — lambda表达式与内置函数

    目录 1 lambda表达式 (匿名函数) 2 内置函数 1 lambda表达式 (匿名函数) 用于表示简单的函数 lambda表达式,为了解决简单函数的情况: def func(a1,a2): == ...

  8. 适合新手的160个creakme(二)

    先跑一下,然后找出关键字符串 关键字符串是You Get Wrong和Try Again,不过IDA好像识别不出来这个字符串,在Ollydbg中右键Search For,寻找所有字符串,可以找到这些字 ...

  9. linux系统安全设置加固

        描述 设置SSH空闲超时退出时间,可降低未授权用户访问其他用户ssh会话的风险 检查提示 -- 加固建议 编辑/etc/ssh/sshd_config,将ClientAliveInterval ...

  10. 怎样使用js将文本复制到系统粘贴板中

    需要使用到三个document方法: 1. document.execCommand(); 执行某个命令 2. document.queryCommandSupported(); 检测浏览器是否支持某 ...