HDU - 6087 Rikka with Sequence (可持久化treap+倍增+重构)
感谢Dream_Lolita的题解,经过无数次失败的尝试之后终于AC了...
线段树是维护区间信息的强大工具,但它的形态是固定的,只支持修改和删除操作,不支持插入、反转、复制、分裂合并等操作,而treap支持。这道题有个区间复制的操作,因此只能用treap来代替了。
注意几个坑点:
1.对于操作2,当k<r-l+1时,不是将[l-k,r-k]中的元素直接替换到[l,r]上,而是将[l-k,l-1]中的元素复制多次再替换到[l,r]上,因此需要对[l-k,l-1]区间反复自我merge直至长度大于等于r-l+1,类似倍增的方式。
2.如果对每个结点设置一个静态的随机因子,那么对区间进行复制时,会产生大量重复的随机因子,严重影响树的平衡性。因此可以去掉随机因子,在对结点u,v进行merge的时候动态取一个随机数rnd,检查rnd%(siz[u]+siz[v])与siz[u]的关系来决定以哪种方式进行合并。考虑到评测OS是Windows,rand函数的上限只有2^15-1,因此可以采用rand()<<15|rand()的方法将两个rand函数拼凑起来,这样上限就扩大到2^30-1了。
3.操作3中的merge可以不用可持久化,但操作2中的merge必须可持久化,否则会出现莫名其妙的错误(这里查错查了很久,我暂时也说不清为什么)
4.本题对内存的限制非常严格,因此需要定期检查结点数量,如果快要超过内存上限了,就要对整个序列进行暴力重构。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=28e5+,inf=0x3f3f3f3f;
int ch[N][],val[N],siz[N],tot,n,m,rt,A,q[],nq;
ll sum[N];
#define l(u) ch[u][0]
#define r(u) ch[u][1]
int rnd() {return rand()<<|rand();}
int newnode(int x) {int u=++tot; val[u]=sum[u]=x,siz[u]=,l(u)=r(u)=; return u;}
int cpy(int u) {int w=++tot; val[w]=val[u],sum[w]=sum[u],siz[w]=siz[u],l(w)=l(u),r(w)=r(u); return w;}
void pu(int u) {siz[u]=siz[l(u)]+siz[r(u)]+,sum[u]=sum[l(u)]+sum[r(u)]+val[u];}
void sp(int w,int k,int& u,int& v) {
if(!w) {u=v=; return;}
if(k>=siz[l(w)]+)u=cpy(w),sp(r(w),k-(siz[l(w)]+),r(u),v),pu(u);
else v=cpy(w),sp(l(w),k,u,l(v)),pu(v);
}
void mg(int& w,int u,int v,int f=) {
if(!u||!v) {w=u|v; return;}
if(rnd()%(siz[u]+siz[v])<siz[u])w=(f?cpy(u):u),mg(r(w),r(u),v,f);
else w=(f?cpy(v):v),mg(l(w),u,l(v),f);
pu(w);
}
void upd(int& u,int l,int r,int k) {
int L,M,R,M2;
sp(u,l-,L,R),sp(L,l-k-,L,M);
while(siz[M]<r-l+)mg(M,M,M,);
sp(M,r-l+,M,M2),sp(u,r,L,R),sp(L,l-,L,M2);
mg(L,L,M,),mg(u,L,R,);
}
void upd2(int& u,int v,int l,int r) {
int L,M,R,M2;
sp(v,r,L,R),sp(L,l-,L,M);
sp(u,r,L,R),sp(L,l-,L,M2);
mg(L,L,M),mg(u,L,R);
}
ll qry(int& u,int l,int r) {
int L,M,R;
sp(u,r,L,R),sp(L,l-,L,M);
ll ret=sum[M];
mg(L,L,M),mg(u,L,R);
return ret;
}
void dfs(int u) {if(!u)return; dfs(l(u)),q[nq++]=val[u],dfs(r(u));}
void build(int& u,int l=,int r=n-) {
if(l>r) {u=; return;}
int mid=(l+r)>>;
u=newnode(q[mid]);
build(l(u),l,mid-),build(r(u),mid+,r),pu(u);
}
void rebuild() {tot=siz[A],nq=,dfs(rt),build(rt);}
int main() {
srand(time());
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i)scanf("%d",&q[i]);
build(A),rt=A;
while(m--) {
int f,l,r,k;
scanf("%d%d%d",&f,&l,&r),l,r;
if(f==)scanf("%d",&k);
if(f==)printf("%lld\n",qry(rt,l,r));
else if(f==)upd(rt,l,r,k);
else if(f==)upd2(rt,A,l,r);
if(tot>)rebuild();
}
return ;
}
HDU - 6087 Rikka with Sequence (可持久化treap+倍增+重构)的更多相关文章
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- HDU 5828 Rikka with Sequence (线段树)
Rikka with Sequence 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- hdu 5204 Rikka with sequence 智商不够系列
Rikka with sequence Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.p ...
- HDU 5828 Rikka with Sequence(线段树 开根号)
Rikka with Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- HDU 5828 Rikka with Sequence(线段树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5828 [题目大意] 给出一个数列,要求支持区间加法,区间开方和区间和查询操作. [题解] 考虑开方 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- HDU 5828 Rikka with Sequence
好久没写线段树了,这题作为一个回味.. 第一种操作的话,就是一个延迟标记. 第二种操作可以暴力更新下去,但是有一个优化,如果某区间内所有值都是一样的,或者最大值和最小值相差1,那么到此结束,不要继续往 ...
随机推荐
- linux上wps2019不能启动解决方法
本人linux上的wps2016升级成wps2019后启动不了,双击图标没反应,在命令行输入wps,提示"/lib64/libc.so.6: version `GLIBC_2.18' not ...
- HCL试验七
在静态路由的基础上实行动态路由 对每台路由器的直连ip编写动态路由命令 路由器1 rip 1 network 192.168.1.0 network 10.1.1.0 undo summary und ...
- 【AMAD】django-rules -- 强大的Django鉴权库,不需要数据库
动机 简介 个人评分 动机 Django默认的权限原子级别是model级.但是一些时候我们像针对model每条数据库记录都进行权限空,也就是对象级权限控制. 简介 django-rules是一个Dja ...
- AI 资源帖
https://github.com/mnielsen/neural-networks-and-deep-learning openCV笔记 https://blog.csdn.net/qq_2689 ...
- appium环境搭建(一)----安装appium
一.安装appium Appium官方网站:http://appium.io/,官方首页给出了appium的安装步骤. > brew install node # get node.js > ...
- CDH目录
配置文件都在:/etc/服务名, 看hadoop的classpath |grep conf /etc/hadoop/conf log都在: /var/log/服务名 看scm的log: tail -1 ...
- P2670 【扫雷游戏】
题面哦~~ lalala~~~ 这题数据并不大,最大不过100*100,所以果断穷举 其实本来我是想边读边做的,但读入是个问题. 主要思路呢,就是读完之后穷举一边,只要是炸弹,就把周围一圈8个加一遍 ...
- HDU-5238 Calculator
题目描述 给定一个关于 \(x\) 的表达式,形如下例:\(×4+2^3+8×6\) 按如下方法计算:\((((x×4)+2)^3+8)×6\) 运算符只有 加号,乘号,幂运算三种,给定的式子中有 \ ...
- python-day37(正式学习)
前景回顾 抢票系统的代码优化,使用了Lock类 from multiprocessing import Process,Lock import os,time,json with open('user ...
- # 关于设置AUTH_USER_MODEL出现的问题
关于设置AUTH_USER_MODEL出现的问题 在运行的时候出现了一个bug: AttributeError: type object 'UserProfile' has no attribute ...