题面传送门

神仙题。

乍一看和经典题 花神游历各国有一点像,只不过多了一个区间加操作。不过多了这个区间加操作就无法再像花神游历各国那样暴力开根直到最小值为 \(1\) 为止的做法了,稍微感性理解一下即可明白,比方说你对一个已经全变为 \(1\) 的长度为 \(10^5\) 区间再加上 \(10^5\),那还需要 \(10^5\times\log 10^5\) 次区间修改操作才能变回原样,这样一来复杂度必然爆炸。

注意到我们对一个区间进行全局加,是不影响它的极差的,因此我们考虑用极差的角度思考这个问题,对于一段区间我们记录它的最大值和最小值,如果它们相等,即极差为 \(0\),那么显然区间开根就可以归约到区间加,直接打个标记即可。否则我们就继续递归左右区间进行修改。

为什么这样复杂度就对了呢?我们考虑记一个区间的为这个区间中元素的极差,不难发现我们对一个区间进行开根后容也会开根,因为假设区间最大值为 \(a\),最小值为 \(b\),那么本来容为 \(a-b\),开根后容为 \(\sqrt{a}-\sqrt{b}\),而 \(a-b=(\sqrt{a}-\sqrt{b})(\sqrt{a}+\sqrt{b})\),故 \(\dfrac{a-b}{\sqrt{a}-\sqrt{b}}>\sqrt{a}-\sqrt{b}\),证毕。也就是说我们对一个区间最多进行 \(\log n\) 次操作即可让它的容变为 \(0\)。

接下来考虑修改操作,由于我们要修改的区间要拆分成 \(\log n\) 个区间,而如果我们对一个区间进行全局加,是不影响它的极差的,因此一次修改最多影响 \(\log n\) 个区间的容,而就算我们将这 \(\log n\) 的区间的容都变得很大,打个比方,都变成 \(10^{10}\),那最多还是只需要 \(\log 10^{10}\times\log n\) 次操作才能将这些区间的容又变回 \(0\),因此每次区间带来的操作次数的影响是 \(\log n\log A\) 的,其中 \(A\) 为值域,因此总复杂度上界为 \(n\log A+m\log n\log A\),且异常跑不满。

但由于下取整可能会带来的误差,直接这样写是无法通过的,比方说序列 \(3\ 4\ 3\ 4\),开根后得到 \(1\ 2\ 1\ 2\),极差不变。因此我们可以构造出这样的 hack 数据:

100000 100000
255 256 255 256 ... 255 256
2 1 100000
2 1 100000
2 1 100000
3 1 100000
1 1 100000 255
2 1 100000
2 1 100000
2 1 100000
3 1 100000
1 1 100000 255
...
2 1 100000
2 1 100000
2 1 100000
3 1 100000
1 1 100000 255

出现这样的情况就 GG 了。

不过不难发现这种情况会发生当且仅当整段序列极差为 \(1\),并且开根后极差仍为 \(1\),这种情况还是可以规约为区间减的形式,稍微特判一下即可。

u1s1 这种题就是说起来好像很简单的亚子,但思考过程还是挺值得玩味的

const int MAXN=1e5;
int n,qu,a[MAXN+5];
struct node{int l,r;ll mx,mn,sum,lz;} s[MAXN*4+5];
void pushup(int k){
s[k].mn=min(s[k<<1].mn,s[k<<1|1].mn);
s[k].mx=max(s[k<<1].mx,s[k<<1|1].mx);
s[k].sum=s[k<<1].sum+s[k<<1|1].sum;
}
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;if(l==r){s[k].mn=s[k].mx=s[k].sum=a[l];return;}
int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);
}
void pushdown(int k){
if(s[k].lz){
s[k<<1].mn+=s[k].lz;s[k<<1].mx+=s[k].lz;s[k<<1].lz+=s[k].lz;
s[k<<1].sum+=s[k].lz*(s[k<<1].r-s[k<<1].l+1);
s[k<<1|1].mn+=s[k].lz;s[k<<1|1].mx+=s[k].lz;s[k<<1|1].lz+=s[k].lz;
s[k<<1|1].sum+=s[k].lz*(s[k<<1|1].r-s[k<<1|1].l+1);
s[k].lz=0;
}
}
void modify(int k,int l,int r,int x){
if(l<=s[k].l&&s[k].r<=r) return s[k].mn+=x,s[k].mx+=x,s[k].sum+=1ll*(r-l+1)*x,s[k].lz+=x,void();
pushdown(k);int mid=s[k].l+s[k].r>>1;
if(r<=mid) modify(k<<1,l,r,x);
else if(l>mid) modify(k<<1|1,l,r,x);
else modify(k<<1,l,mid,x),modify(k<<1|1,mid+1,r,x);
pushup(k);
}
ll query(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r) return s[k].sum;
pushdown(k);int mid=s[k].l+s[k].r>>1;
if(r<=mid) return query(k<<1,l,r);
else if(l>mid) return query(k<<1|1,l,r);
else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
}
void sqrt(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r){
ll mnv=(ll)sqrt(s[k].mn),mxv=(ll)sqrt(s[k].mx);
if(s[k].mn==s[k].mx){
ll dif=mnv-s[k].mn;
s[k].mn+=dif;s[k].mx+=dif;s[k].sum+=dif*(r-l+1);s[k].lz+=dif;
} else if(s[k].mx-s[k].mn==1&&mxv-mnv==1){
ll dif=mnv-s[k].mn;
s[k].mn+=dif;s[k].mx+=dif;s[k].sum+=dif*(r-l+1);s[k].lz+=dif;
} else {
int mid=l+r>>1;pushdown(k);
sqrt(k<<1,l,mid);sqrt(k<<1|1,mid+1,r);
pushup(k);
} return;
} pushdown(k);int mid=s[k].l+s[k].r>>1;
if(r<=mid) sqrt(k<<1,l,r);
else if(l>mid) sqrt(k<<1|1,l,r);
else sqrt(k<<1,l,mid),sqrt(k<<1|1,mid+1,r);
pushup(k);
}
int main(){
scanf("%d%d",&n,&qu);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
while(qu--){
int opt,l,r,x;scanf("%d",&opt);
switch(opt){
case 1:{scanf("%d%d%d",&l,&r,&x);modify(1,l,r,x);break;}
case 2:{scanf("%d%d",&l,&r);sqrt(1,l,r);break;}
case 3:{scanf("%d%d",&l,&r);printf("%lld\n",query(1,l,r));break;}
}
}
return 0;
}

UOJ #228 - 基础数据结构练习题(势能线段树+复杂度分析)的更多相关文章

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

    传送门 只有区间加区间开方我都会--然而加在一起我就gg了-- 然后这题的做法就是对于区间加直接打标记,对于区间开方,如果这个区间的最大值等于最小值就直接区间覆盖(据ljh_2000大佬说这个区间覆盖 ...

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

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

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

    [UOJ228]基础数据结构练习题(线段树) 题面 UOJ 题解 我们来看看怎么开根? 如果区间所有值都相等怎么办? 显然可以直接开根 如果\(max-sqrt(max)=min-sqrt(min)\ ...

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

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

  5. uoj#228 基础数据结构练习题

    题面:http://uoj.ac/problem/228 正解:线段树. 我们可以发现,开根号时一个区间中的数总是趋近相等.判断一个区间的数是否相等,只要判断最大值和最小值是否相等就行了.如果这个区间 ...

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

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

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

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

  8. HDU6315 Naive Operations(线段树 复杂度分析)

    题意 题目链接 Sol 这题关键是注意到题目中的\(b\)是个排列 那么最终的答案最多是\(nlogn\)(调和级数) 设\(d_i\)表示\(i\)号节点还需要加\(d_i\)次才能产生\(1\)的 ...

  9. uoj#119. 【UR #8】决战圆锥曲线(线段树+复杂度分析)

    题解 传送门 题解 然而要我来说我感觉只是个爆搜啊-- //minamoto #include<bits/stdc++.h> #define R register #define ll l ...

随机推荐

  1. 保护模式篇——PAE分页

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  2. 【c++ Prime 学习笔记】第4章 表达式

    表达式由一个或多个运算对象组成,对表达式求值返回结果. 字面值和变量是最简单的表达式 把运算符和运算对象组合可得到复杂表达式. 4.1 基础 4.1.1 基本概念 一元运算符作用于一个对象,如取地址符 ...

  3. [Beta]the Agiles Scrum Meeting 1

    会议时间:2020.5.9 21:00 1.每个人的工作 今天已完成的工作 讨论转会事项 经过组内成员的讨论,我们做出了非常艰难的决定:我们的组员老c将作为转会成员,离开我们的团队.感谢老c在Alph ...

  4. git为单独的仓库设置提交的用户名

    在我们平时的学习中可能有这么一种需求,在公司进行开发的时候,一般会参与多个项目的开发,而项目提交代码时,一般请求情况下提供的用户都是同一个,而我们为了方便可能会使用全局进行git 用户名的配置.但是空 ...

  5. 2021.7.28考试总结[NOIP模拟26]

    罕见的又改完了. T1 神炎皇 吸取昨天三个出规律的教训,开场打完T2 20pts直接大力打表1h. 但怎么说呢,我不懂欧拉函数.(其实exgcd都忘了 于是只看出最大平方因子,不得不线性筛,爆拿60 ...

  6. Linux C语言链表你学会了吗?

    链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用.链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节 ...

  7. 洛谷 P3195 [HNOI2008] 玩具装箱

    链接: P3195 题意: 给出 \(n\) 个物品及其权值 \(c\),连续的物品可以放进一个容器,如果将 \(i\sim j\) 的物品放进一个容器,产生的费用是 \(\left(j-i+\sum ...

  8. Django(71)图片处理器django-imagekit

    介绍 ImageKit是用于处理图像的Django应用程序.如果需要从原图上生成一个长宽为50x50的图像,则需要ImageKit. ImageKit附带了一系列图像处理器,用于调整大小和裁剪等常见任 ...

  9. 跳台阶 牛客网 剑指Offer

    跳台阶 牛客网 剑指Offer 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). class Solution: #ru ...

  10. HTML 罗盘式时钟

    代码块: 1 <!DOCTYPE html> 2 <html lang="zh-hans"> 3 <head> 4 <meta chars ...