BZOJ 3065 带插入区间K小值
http://www.lydsy.com/JudgeOnline/problem.php?id=3065
思路:替罪羊树套权值线段树。
当替罪羊树某个子树大于某个比利(比例)时就暴力重构,本题时间复杂度:O(nlog^3n)
- #include<algorithm>
- #include<cstdio>
- #include<cmath>
- #include<cstring>
- #include<iostream>
- #include<vector>
- #define alpha 0.75
- #define N 10000005
- int read(){
- char ch=getchar();int t=,f=;
- while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
- while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
- return t*f;
- }
- int tmp;
- int n,m,sz,ans,root;
- int v[],dfn[],rt[],ls[],rs[];
- struct seg{int l,r,sum;}a[N];
- std::vector<int>p,t,rec;
- int newnode(){
- if (!rec.size()) return ++sz;
- else{
- int k=rec.back();rec.pop_back();
- return k;
- }
- }
- void recliam(int &x){
- if (!x) return;
- rec.push_back(x);
- recliam(a[x].l);recliam(a[x].r);
- a[x].sum=;x=;
- }
- void insert(int &k,int l,int r,int val,int f){
- if (!k) k=newnode();
- if (l==r){a[k].sum+=f;return;}
- int mid=(l+r)>>;
- if (val<=mid) insert(a[k].l,l,mid,val,f);
- else insert(a[k].r,mid+,r,val,f);
- a[k].sum=a[a[k].l].sum+a[a[k].r].sum;
- if (!a[k].sum) recliam(k);
- }
- void build(int &k,int l,int r){
- int mid=(l+r)>>;
- if (l>r) return;
- if (l==r){
- k=dfn[l];insert(rt[k],,,v[k],);return;
- }
- k=dfn[mid];
- build(ls[k],l,mid-);build(rs[k],mid+,r);
- for (int i=l;i<=r;i++)
- insert(rt[k],,,v[dfn[i]],);
- }
- void del(int &x){
- if (!x) return;recliam(rt[x]);
- del(ls[x]);p.push_back(x);del(rs[x]);
- x=;
- }
- void rebuild(int &x){
- del(x);int s1=p.size();
- for (int i=;i<=s1;i++) dfn[i]=p[i-];
- build(x,,s1);
- p.clear();
- }
- int modify(int k,int x,int val){
- insert(rt[k],,,val,);
- int t,L=a[rt[ls[k]]].sum;
- if (L+==x){t=v[k];v[k]=val;}
- else if (L>=x) t=modify(ls[k],x,val);
- else t=modify(rs[k],x-L-,val);
- insert(rt[k],,,t,-);
- return t;
- }
- void query(int k,int l,int r){
- int L=a[rt[ls[k]]].sum,R=a[rt[k]].sum;
- if (l==&&r==R){t.push_back(rt[k]);return;}
- if (l<=L+&&r>=L+)p.push_back(v[k]);
- if (r<=L)query(ls[k],l,r);
- else if (l>L+) query(rs[k],l-L-,r-L-);
- else{
- if (l<=L) query(ls[k],l,L);
- if (R>L+) query(rs[k],,r-L-);
- }
- }
- int solve_query(int L,int R,int K){
- query(root,L,R);K--;
- int l=,r=,s1=t.size(),s2=p.size();
- while (l<r){
- int mid=(l+r)>>,sum=;
- for (int i=;i<s1;i++) sum+=a[a[t[i]].l].sum;
- for (int i=;i<s2;i++)
- if (p[i]>=l&&p[i]<=mid) sum++;
- if (K<sum){
- for (int i=;i<s1;i++) t[i]=a[t[i]].l;
- r=mid;
- } else{
- for (int i=;i<s1;i++) t[i]=a[t[i]].r;
- l=mid+;K-=sum;
- }
- }
- t.clear();p.clear();
- return l;
- }
- void insert(int &k,int x,int val){
- if (!k){
- k=++n;
- insert(rt[k],,,val,);
- v[k]=val;
- return;
- }
- insert(rt[k],,,val,);
- int L=a[rt[ls[k]]].sum;
- if (L>=x) insert(ls[k],x,val);else insert(rs[k],x-L-,val);
- if (a[rt[k]].sum*alpha>std::max((double)a[rt[ls[k]]].sum,(double)a[rt[rs[k]]].sum)){
- if (tmp){
- if (ls[k]==tmp) rebuild(ls[k]);
- else rebuild(rs[k]);
- tmp=;
- }
- }else tmp=k;
- }
- int main(){
- n=read();
- for (int i=;i<=n;i++) v[i]=read();
- for (int i=;i<=n;i++) dfn[i]=i;
- build(root,,n);
- m=read();
- char ch[];int x,y,K;
- while (m--){
- scanf("%s",ch);
- x=read();y=read();x^=ans;y^=ans;
- switch(ch[]){
- case 'Q':K=read();K^=ans;ans=solve_query(x,y,K);printf("%d\n",ans);break;
- case 'M':modify(root,x,y);break;
- case 'I':tmp=;insert(root,x-,y);if (tmp){tmp=;rebuild(root);}break;
- }
- }
- }
BZOJ 3065 带插入区间K小值的更多相关文章
- bzoj 3065: 带插入区间K小值 替罪羊树 && AC300
3065: 带插入区间K小值 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1062 Solved: 253[Submit][Status] Des ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- BZOJ 3065 带插入区间K小值(sag套线段树)
3065: 带插入区间K小值 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 4696 Solved: 1527[Submit][Status][Di ...
- bzoj 3065: 带插入区间K小值(分块)
Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它 ...
- BZOJ 3065 带插入区间K小值 (替罪羊树套线段树)
毒瘤题.参考抄自博客:hzwer 第一次写替罪羊树,完全是照着题解写的,发现这玩意儿好强啊,不用旋转每次都重构还能nlognnlognnlogn. 还有外面二分和里面线段树的值域一样,那么r = mi ...
- 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树
经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...
- 【BZOJ】3065: 带插入区间K小值
http://www.lydsy.com/JudgeOnline/problem.php?id=3065 题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175 ...
- 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值
常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...
- [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树
刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...
随机推荐
- android里Toast的用法
在活动中,可以通过findViewById()方法获取到在布局文件中定义的元素,这里我们传入R.id.button_1,来得到按钮的实例,这个值是刚才在first_layout.xml中通过andro ...
- Appium官网Introduction
英文官网:http://appium.io/introduction.html?lang=zh Appium 简介 Appium是一个开源的自动化测试工具,其支持iOS和安卓平台上的原生的,基于移动浏 ...
- 用htaccess进行访问控制(转)
1. 文件访问控制 利用 httpd.conf 中的 Order.Files 及 FilesMatch 命令实现的访问控制可以满足大部分要求,但是当用户被拒绝时,他们看到的是硕大的“403 Forbi ...
- spring mvc DispatcherServlet详解之一---处理请求深入解析
要深入理解spring mvc的工作流程,就需要先了解spring mvc的架构: 从上图可以看到 前端控制器DispatcherServlet在其中起着主导作用,理解了DispatcherServl ...
- Servlet与JSP的关系
Servlet与JSP的异同点: 相似点: 都可以生成动态网页 不同点: JSP擅长网页制作,生成页面直观,但不易追踪与排错 Servlet是纯Java,擅长处理流程与业务逻辑,缺点是页面不直观
- HDU3480
题意:给你n个数,然后让你分成m个集合,每个集合有一个值(最大值减最小值,然后平方),求整个集合的可能最小值. 思路:因为每个集合里的值只和最大和最小值有关,所以很容易想到先排序,然后用DP可求得解, ...
- @ManyToMany 两个表多对多关联
两个表属于多对多关系 如 Teacher <=> Student 表teacher 主键 id 表student 主键id 中间关联表 teacher_student 两个字段 t_id ...
- jquer “$” 扩展(笔记)
/** * Created by shanruo on 16-03-10. */ (function ( $ ){ $.extend ({ /* * 根据参数名获取参数 @name String 参数 ...
- 7-ajax的同步和异步?
同步和异步统一根据send()执行的位置来实现分割逻辑同步:1.send()后统一不会被执行,直到http事务完成之后才会之后后续逻辑.2.堵塞send()方法的逻辑.异步:1.send()后面照样执 ...
- Linux filesystem structures.
1. / – Root Every single file and directory starts from the root directory. Only root user has write ...