【UOJ228】基础数据结构练习题(线段树)

题面

UOJ

题解

我们来看看怎么开根?

如果区间所有值都相等怎么办?

显然可以直接开根

如果\(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】基础数据结构练习题(线段树)的更多相关文章

  1. [UOJ228] 基础数据结构练习题 - 线段树

    考虑到一个数开根号 \(loglog\) 次后就会变成1,设某个Node的势能为 \(loglog(maxv-minv)\) ,那么一次根号操作会使得势能下降 \(1\) ,一次加操作最多增加 \(l ...

  2. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  3. uoj #228. 基础数据结构练习题 线段树

    #228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...

  4. 【uoj#228】基础数据结构练习题 线段树+均摊分析

    题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加.区间开根.区间求和. $n,m,a_i\le 100000$ . 题解 线段树+均摊分析 对于原来的两个数 $a$ ...

  5. uoj#228. 基础数据结构练习题(线段树区间开方)

    题目链接:http://uoj.ac/problem/228 代码:(先开个坑在这个地方) #include<bits/stdc++.h> using namespace std; ; l ...

  6. UOJ #228. 基础数据结构练习题 线段树 + 均摊分析 + 神题

    题目链接 一个数被开方 #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",st ...

  7. uoj228 基础数据结构练习题

    趁别人题解没有放出来赶快写一篇 整数序列,操作 区间加 区间变成sqrt(下取整) 区间和 考虑一下对于每个区间里所有sqrt不同的段操作,那么可以在O(段数logn)一次的时间内完成sqrt操作.考 ...

  8. 【线段树】uoj#228. 基础数据结构练习题

    get到了标记永久化 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的好朋友九条可怜酱给她出了一道题. 给出一 ...

  9. 数据结构-PHP 线段树的实现

    转: 数据结构-PHP 线段树的实现 1.线段树介绍 线段树是基于区间的统计查询,线段树是一种 二叉搜索树,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.使用线段树可以快速的查 ...

随机推荐

  1. 使用request+Beautiful爬取妹子图

    一.request安装 pip install requests request使用示例 import requests response = requests.get('https://www.mz ...

  2. 在WebGL场景中进行棋盘操作的实验

    这篇文章讨论如何在基于Babylon.js的WebGL场景中,建立棋盘状的地块和多个可选择的棋子对象,在点选棋子时显示棋子的移动范围,并且在点击移动范围内的空白地块时向目标地块移动棋子.在这一过程中要 ...

  3. docker 下载安装与配置

    # mac离线安装dockerhttps://download.docker.com/mac/stable/24312/Docker.dmg # windows离线安装dockerhttp://mir ...

  4. Java 快排 排序

    一.快排的一种 ==================== public class myMain { public static void main(String[] args) { int t[] ...

  5. DockerCon2017前瞻 - Docker企业版体验

    DockerCon 2017将于四月17号在美国Austin召开.在去年DockerCon上,Docker公司一系列的发布吹响了进军企业市场的号角.今天,容器技术已经愈发成熟,被越来越多的企业所关注和 ...

  6. eclipse在线安装maven插件

    http://blog.csdn.net/xiaoxiaoyeyaya/article/details/17200987 在安装插件的时候将下面的contact all update sites du ...

  7. mysql/mybatis之合并两个表的查询结果

    下面这段sql是把两个表中各自符合条件的count值相加,返回结果是两个之和 SELECT sum(result) FROM ( SELECT COUNT(*) result FROM TEST_A ...

  8. Daily Scrumming* 2015.10.30(Day 11)

    一.总体情况总结 今日项目总结: 1.前后端同一了API设计以及API权限认证.用户状态保存的开发方案 2.API以及后端模型已经开始开发,前端UEditor开始学习,本周任务有良好的起步 3.前后端 ...

  9. MathExam6378

    我的第一个程序 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 15 10 • Estima ...

  10. WebGL学习笔记五

    本章主要是对纹理的进一步讲解,我们很多时候需要将现实中已有 的图片在网页中展示出来而不是去创造图片,通过纹理 我们可以将光栅化的图形和图片纹理形成映射并且将图片在图形 中显示出来.基本过程与前几章一致 ...