题意

给出一些数,有两种操作。(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. 解决redis运行期间key值过期但是内存memory依然占用过高

    要解决这个问题,首先要了解redis info信息中几个数据的意义:   used_memory:810575104 //数据占用了多少内存(字节)  used_memory_human:773.02 ...

  2. 二进制协议gob和msgpack介绍

    二进制协议gob和msgpack介绍 本文主要介绍二进制协议gob及msgpack的基本使用. 最近在写一个gin框架的session服务时遇到了一个问题,Go语言中的json包在序列化空接口存放的数 ...

  3. 5-MySQL DBA笔记-开发技巧

    第5章 开发技巧 本章将介绍一些和数据库相关的开发技巧.由于开发领域很广,这里只选取部分比较常见的小技巧.5.1 存储树形数据 有时我们需要保存一些树形的数据结构,比如组织架构.话题讨论.知识管理.商 ...

  4. dotnet跨平台 - 使用Nginx+Docker Compose运行.NETCore项目

    参考文档: https://docs.docker.com/install/linux/docker-ce/centos/ http://www.dockerinfo.net/document htt ...

  5. sql 行数据找出最大的及所有数据最大的

    SELECT @charges=ISNULL(MAX(a.maxcharge), 0.00) FROM( SELECT (SELECT MAX(maxcharge) FROM(VALUES(ilong ...

  6. 关键字:for_each

    std::for_each 先贴cppreference中对for_each的概述: template< class InputIt, class UnaryFunction > //此处 ...

  7. struts-2.5.14.1中jar包引入

  8. 使用2种python脚本工具将2个txt文档中的文字进行比较,并计算出Corr, WER正确率,准确率

    一.准备: linux服务器,src2mlf.py   rec2mlf.py   HResults文件,1份源文件和1份需要对比的文件.文件放置于本人云盘 二.使用方法: 1. 对比工具 HResul ...

  9. DICOM文件修改方法

    /// <summary> /// 读取dicom文件 /// </summary> /// <param name="srcdirectory"&g ...

  10. 【51nod2026】Gcd and Lcm(杜教筛)

    题目传送门:51nod 我们可以先观察一下这个$f(x)=\sum_{d|x}\mu(d) \cdot d$. 首先它是个积性函数,并且$f(p^k)=1-p \ (k>0)$,这说明函数$f( ...