uoj#228. 基础数据结构练习题(线段树)
只有区间加区间开方我都会……然而加在一起我就gg了……
然后这题的做法就是对于区间加直接打标记,对于区间开方,如果这个区间的最大值等于最小值就直接区间覆盖(据ljh_2000大佬说这个区间覆盖可以改成区间减去一个数),否则的话如果最小值等于最大值加一,且最小值和最大值开方之后减少的值一样,也直接打上区间减标记,否则递归下去
考虑复杂度,如果两个相邻的点导致包含这两个点的区间必须从这里分开才能进行开根操作,那么就称其为一个分界点,一个分界点相当于把区间开根分成两次。因为序列的初始值小于等于\(10^5\),最多开根\(4\)次分界点就会消失,而区间加的权值也小于等于\(10^5\),最多增加两个点\(4\)次开根,常数而已
然后试了试ljh_2000大佬说的标记永久化+不下传……跑得贼快啊……
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define ls (p<<1)
#define rs (p<<1|1)
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
inline ll max(const R ll &x,const R ll &y){return x>y?x:y;}
inline ll min(const R ll &x,const R ll &y){return x<y?x:y;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5;
struct node{int len;ll sum,tag,mn,mx;}tr[N<<2];
int n,m,a[N],ql,qr,val,op;ll ans;
inline void pd(R node &x,R ll v){x.tag+=v,x.mn+=v,x.mx+=v,x.sum+=v*x.len;}
void upd(R int p){
tr[p].sum=tr[ls].sum+tr[rs].sum+tr[p].tag*tr[p].len;
tr[p].mx=max(tr[ls].mx,tr[rs].mx)+tr[p].tag;
tr[p].mn=min(tr[ls].mn,tr[rs].mn)+tr[p].tag;
}
void build(int p,int l,int r){
tr[p].len=r-l+1;
if(l==r)return (void)(tr[p].sum=tr[p].mx=tr[p].mn=a[l]);
int mid=(l+r)>>1;
build(ls,l,mid),build(rs,mid+1,r);
upd(p);
}
void update(int p,int l,int r){
if(ql<=l&&qr>=r)return pd(tr[p],val);
int mid=(l+r)>>1;
if(ql<=mid)update(ls,l,mid);
if(qr>mid)update(rs,mid+1,r);
upd(p);
}
void Sqrt(int p,int l,int r,ll tag){
if(ql<=l&&qr>=r){
if(tr[p].mx==tr[p].mn){
ll del=tr[p].mn+tag-(ll)sqrt(tr[p].mn+tag);
return pd(tr[p],-del);
}
ll c1=sqrt(tr[p].mn+tag)+1,c2=sqrt(tr[p].mx+tag);
if(tr[p].mx==tr[p].mn+1&&c1==c2){
ll del=tr[p].mn+tag-(ll)sqrt(tr[p].mn+tag);
return pd(tr[p],-del);
}
}
int mid=(l+r)>>1;
if(ql<=mid)Sqrt(ls,l,mid,tag+tr[p].tag);
if(qr>mid)Sqrt(rs,mid+1,r,tag+tr[p].tag);
upd(p);
}
void query(int p,int l,int r,ll tag){
if(ql<=l&&qr>=r)return (void)(ans+=tr[p].sum+tr[p].len*tag);
int mid=(l+r)>>1;
if(ql<=mid)query(ls,l,mid,tag+tr[p].tag);
if(qr>mid)query(rs,mid+1,r,tag+tr[p].tag);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
fp(i,1,n)a[i]=read();
build(1,1,n);
while(m--){
op=read(),ql=read(),qr=read();
switch(op){
case 1:val=read(),update(1,1,n);break;
case 2:Sqrt(1,1,n,0);break;
case 3:ans=0;query(1,1,n,0);print(ans);break;
}
}return Ot(),0;
}
uoj#228. 基础数据结构练习题(线段树)的更多相关文章
- uoj #228. 基础数据结构练习题 线段树
#228. 基础数据结构练习题 统计 描述 提交 自定义测试 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的 ...
- 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 ...
- 【线段树】uoj#228. 基础数据结构练习题
get到了标记永久化 sylvia 是一个热爱学习的女孩子,今天她想要学习数据结构技巧. 在看了一些博客学了一些姿势后,她想要找一些数据结构题来练练手.于是她的好朋友九条可怜酱给她出了一道题. 给出一 ...
- 【UOJ#228】基础数据结构练习题 线段树
#228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...
- uoj#228 基础数据结构练习题
题面:http://uoj.ac/problem/228 正解:线段树. 我们可以发现,开根号时一个区间中的数总是趋近相等.判断一个区间的数是否相等,只要判断最大值和最小值是否相等就行了.如果这个区间 ...
- 【uoj#228】基础数据结构练习题 线段树+均摊分析
题目描述 给出一个长度为 $n$ 的序列,支持 $m$ 次操作,操作有三种:区间加.区间开根.区间求和. $n,m,a_i\le 100000$ . 题解 线段树+均摊分析 对于原来的两个数 $a$ ...
- UOJ #228 - 基础数据结构练习题(势能线段树+复杂度分析)
题面传送门 神仙题. 乍一看和经典题 花神游历各国有一点像,只不过多了一个区间加操作.不过多了这个区间加操作就无法再像花神游历各国那样暴力开根直到最小值为 \(1\) 为止的做法了,稍微感性理解一下即 ...
- [UOJ228] 基础数据结构练习题 - 线段树
考虑到一个数开根号 \(loglog\) 次后就会变成1,设某个Node的势能为 \(loglog(maxv-minv)\) ,那么一次根号操作会使得势能下降 \(1\) ,一次加操作最多增加 \(l ...
随机推荐
- wifi debug command
==================================================================================================== ...
- Web框架和Django基础
核心知识点 1.web应用类似于一个socket客户端,用来接收请求 2.HTTP:规定了客户端和服务器之间的通信格式. 3.一个HTTP包含两部分,header和body,body是可选,\r\n分 ...
- Eclipse的.properties文件输出中文成unicode编码
今天添加log4j.properties时,无法输入中文,输入的中文直接变成了unicode的编码形式.原因是Eclipse的.properties文件的默认编码为iso-8859-1. 选择Wind ...
- 校园网络 usaco
这道题和上一道[最受欢迎的牛]差不多,都是强连通分量的练习题: 第一问实际上就是问缩点后入度为0的点有多少,第二问就是问添加几条边能使缩点后的图变成强连通图: 第一问好做,第二问需要动下脑子,也不难: ...
- Makefile中的$(@:_config=)什么意思?【转】
本文转载自:https://blog.csdn.net/a8082649/article/details/24252093 已经编译出bin文件了,现在研究一下makefile,把遇到的问题记录下来: ...
- 郝健: Linux内存管理学习笔记-第1节课【转】
本文转载自:https://blog.csdn.net/juS3Ve/article/details/80035751 摘要 MMU与分页机制 内存区域(内存分ZONE) LinuxBuddy分配算法 ...
- ActiveMQ之发布、订阅使用
maven依赖 <dependencies> <dependency> <groupId>org.apache.activemq</groupId> & ...
- python的小知识点
python中的变量的名字必须由字母.数字.下划线组成,并且不可以以数字开头. 字典的内容是键-值对,键必须是不可变的,比如字符,整数,浮点数,元组,列表不可以,因为列表可变.集合的元素不重复.字典和 ...
- 从TS流到PAT和PMT
转自:https://blog.csdn.net/rongdeguoqian/article/details/18214627 一 从TS流开始 最近开始学习数字电视机顶盒的开发,从MPEG-2到DV ...
- 《java编程思想》:第五章,初始化与清理
知识点整理: 1.从概念上讲,‘初始化’与‘创建’是彼此独立的,但是在Java中,两者被捆绑在一起,不可分离. 2.区分重载的方法:每个重载的方法都有一个独一无二的参数类型列表. 甚至参数顺序的不同也 ...