【UOJ228】基础数据结构练习题(线段树)
【UOJ228】基础数据结构练习题(线段树)
题面
题解
我们来看看怎么开根?
如果区间所有值都相等怎么办?
显然可以直接开根
如果\(max-sqrt(max)=min-sqrt(min)\)怎么办?
此时意味着虽然开根出来的值不同,但是减去的值相同
举个例子,比如\(8,9\)
开根后是\(2,3\)
虽然值不同,但是差相同
所以,我们把开根换成区间减法
当出现上述两种情况时下放减法标记即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 120000
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,m,A[MAX];
struct Node{ll v,mx,mn,tag;}t[MAX<<2];
void Build(int now,int l,int r)
{
if(l==r){t[now].v=t[now].mx=t[now].mn=A[l];return;}
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
t[now].v=t[lson].v+t[rson].v;
t[now].mx=max(t[lson].mx,t[rson].mx);
t[now].mn=min(t[lson].mn,t[rson].mn);
}
void puttag(int now,int l,int r,ll w)
{
t[now].v+=w*(r-l+1);
t[now].mx+=w;t[now].mn+=w;
t[now].tag+=w;
}
void pushdown(int now,int l,int r)
{
if(t[now].tag==0)return;
int mid=(l+r)>>1;
puttag(lson,l,mid,t[now].tag);
puttag(rson,mid+1,r,t[now].tag);
t[now].tag=0;
}
void Modify_Plus(int now,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){puttag(now,l,r,w);return;}
pushdown(now,l,r);
int mid=(l+r)>>1;
if(L<=mid)Modify_Plus(lson,l,mid,L,R,w);
if(R>mid)Modify_Plus(rson,mid+1,r,L,R,w);
t[now].v=t[lson].v+t[rson].v;
t[now].mx=max(t[lson].mx,t[rson].mx);
t[now].mn=min(t[lson].mn,t[rson].mn);
}
void Modify_Sqrt(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
ll a=sqrt(t[now].mx),b=sqrt(t[now].mn);
if(t[now].mx==t[now].mn){puttag(now,l,r,a-t[now].mx);return;}
if(t[now].mx-a==t[now].mn-b){puttag(now,l,r,a-t[now].mx);return;}
}
pushdown(now,l,r);
int mid=(l+r)>>1;
if(L<=mid)Modify_Sqrt(lson,l,mid,L,R);
if(R>mid)Modify_Sqrt(rson,mid+1,r,L,R);
t[now].v=t[lson].v+t[rson].v;
t[now].mx=max(t[lson].mx,t[rson].mx);
t[now].mn=min(t[lson].mn,t[rson].mn);
}
ll Query(int now,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return t[now].v;
pushdown(now,l,r);
int mid=(l+r)>>1;ll ret=0;
if(L<=mid)ret+=Query(lson,l,mid,L,R);
if(R>mid)ret+=Query(rson,mid+1,r,L,R);
t[now].v=t[lson].v+t[rson].v;
t[now].mx=max(t[lson].mx,t[rson].mx);
t[now].mn=min(t[lson].mn,t[rson].mn);
return ret;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;++i)A[i]=read();
Build(1,1,n);
while(m--)
{
int opt=read(),l=read(),r=read();
if(opt==1)Modify_Plus(1,1,n,l,r,read());
else if(opt==2)Modify_Sqrt(1,1,n,l,r);
else printf("%lld\n",Query(1,1,n,l,r));
}
return 0;
}
【UOJ228】基础数据结构练习题(线段树)的更多相关文章
- [UOJ228] 基础数据结构练习题 - 线段树
考虑到一个数开根号 \(loglog\) 次后就会变成1,设某个Node的势能为 \(loglog(maxv-minv)\) ,那么一次根号操作会使得势能下降 \(1\) ,一次加操作最多增加 \(l ...
- 【UOJ#228】基础数据结构练习题 线段树
#228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...
- uoj #228. 基础数据结构练习题 线段树
#228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...
- 【uoj#228】基础数据结构练习题 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加.区间开根.区间求和. $n,m,a_i\le 100000$ . 题解 线段树+均摊分析 对于原来的两个数 $a$ ...
- uoj#228. 基础数据结构练习题(线段树区间开方)
题目链接:http://uoj.ac/problem/228 代码:(先开个坑在这个地方) #include<bits/stdc++.h> using namespace std; ; l ...
- UOJ #228. 基础数据结构练习题 线段树 + 均摊分析 + 神题
题目链接 一个数被开方 #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",st ...
- uoj228 基础数据结构练习题
趁别人题解没有放出来赶快写一篇 整数序列,操作 区间加 区间变成sqrt(下取整) 区间和 考虑一下对于每个区间里所有sqrt不同的段操作,那么可以在O(段数logn)一次的时间内完成sqrt操作.考 ...
- 【线段树】uoj#228. 基础数据结构练习题
get到了标记永久化 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的好朋友九条可怜酱给她出了一道题. 给出一 ...
- 数据结构-PHP 线段树的实现
转: 数据结构-PHP 线段树的实现 1.线段树介绍 线段树是基于区间的统计查询,线段树是一种 二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查 ...
随机推荐
- python的类和对象2(self参数)
python的类和对象2(self参数) 1.python里面对象的方法都会有self参数,它就相当于C++里面的this指针:绑定方法,据说有了这个参数,Python 再也不会傻傻分不清是哪个对象在 ...
- jQuery的$ .ajax防止重复提交的方法
没啥说的直接贴代码,很简单: 第一种方式:的onclick点击事件类型 <SCRIPT> function member_del(obj,id){ var lock = false; // ...
- 使用python实现解析二元一次方程
二元一次函数的实现 import cmathimport mathimport sys 这里导入cmath包是在后面用来处理复数的情况导入math使用来处理 平方 根号等的运算而导入sys的意义是为了 ...
- 转载:XGBOOST算法梳理
学习内容: CART树 算法原理 损失函数 分裂结点算法 正则化 对缺失值处理 优缺点 应用场景 sklearn参数 转自:https://zhuanlan.zhihu.com/p/58221959 ...
- proxyTable中pathWrrite的使用
proxyTable中pathWrrite的使用 proxyTable: { '/iclient': { target: 'http://xxx.xx.com/iclient/xx/xx', chan ...
- 第31次Scrum会议(11/19)【欢迎来怼】
一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/19 17:05~17:34,总计29min. 地 ...
- 互评Beta版本-SkyHunter
基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题; N(Need,需求):飞机大战题材的游戏对80,90后的人来说算是童年的记忆,可以在闲暇之余打开电脑玩一会儿.但是 ...
- OO第一阶段作业总结
对于OO这门课,学长学姐偶尔提起,大家都略有耳闻,但是并没有将其和计组相提并论.因此,在刚开始接触的时候,并不认为其会比计组难到哪里去,然而事实证明,还是不要想当然去判断,以及不提前学好JAVA对于O ...
- Linux读书笔记第一、二章
第一章 Linux内核简介 1.1Unix历史 Unix特点:1.很简洁 2.所有东西都被当成文件对待 3.Unix内核和相关的系统工具软件都是用C语言编写而成 4.进程创建非常迅速 1.2追寻 ...
- 《[C#] int与System.Int32有什么区别》
最近园里的TeamOne写了一篇<[C#] int与System.Int32有什么区别>,发现里面有不少精彩的评论,所以忍不住想这篇文章总结一下:> 本文的主要参考资料: 1.< ...