经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题.

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
// 带插入区间 k 小值
// 外层:替罪羊
// 内层:权值线段树
using namespace std;
#define setIO(s) freopen(s".in","r",stdin), freopen(s".out","w",stdout)
#define debug() printf("OK\n")
#define maxn 11005000
#define N 70002
int n,lastans;
struct Segment_Tree{
struct Node{
int ls,rs,siz;
Node(int ls=0,int rs=0,int siz=0):ls(ls),rs(rs),siz(siz){}
}node[maxn];
queue<int>Q;
void init(){ for(int i=1;i<maxn;++i) Q.push(i); }
void newnode(int &o) { o=Q.front(), Q.pop(); }
void update(int l,int r,int &o,int pos,int delta){
if(!o) newnode(o);
node[o].siz+=delta;
if(!node[o].siz) { dfs(o); return; }
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) update(l,mid,node[o].ls,pos,delta);
else update(mid+1,r,node[o].rs,pos,delta);
}
void dfs(int &o){
if(!o)return;
dfs(node[o].ls),Q.push(o),dfs(node[o].rs);
node[o].siz=0;
o=0;
}
}segin;
struct Binary_Search_Tree{
inline bool check(int son,int o){
if(son*10>=o*9) return true;
return false;
}
int cnt,root;
int seq[N],count[3];
vector<int>re;
struct Node{
int ls,rs,siz,root,cur,val;
Node(int ls=0,int rs=0,int siz=0,int root=0,int cur=0,int val=0):ls(ls),rs(rs),root(root),cur(cur),val(val){}
}node[maxn];
inline void newnode(int &o,int val){ o=++cnt,node[o].val=val,node[o].siz=1; }
void dfs(int &o){
if(!o) return;
segin.dfs(node[o].root),segin.dfs(node[o].cur);
dfs(node[o].ls),re.push_back(o),dfs(node[o].rs);
node[o].siz=0;
o=0; }
void construct(int l,int r,int &o){
if(l>r)return;
int mid=(l+r)>>1;
o=re[mid]; for(int i=l;i<=r;++i)
segin.update(0,N,node[o].root,node[re[i]].val,1); segin.update(0,N,node[o].cur,node[o].val,1);
if(l==r){ node[o].siz=1; return; } construct(l,mid-1,node[o].ls), construct(mid+1,r,node[o].rs);
node[o].siz=node[node[o].ls].siz+node[node[o].rs].siz+1;
}
inline void Rebuild(int &o){ re.clear(),dfs(o),construct(0,re.size()-1,o); }
void insert(int &o,int k,int val,bool is){
if(!o){
newnode(o,val),segin.update(0,N,node[o].root,val,1),segin.update(0,N,node[o].cur,val,1);
return;
}
++node[o].siz, segin.update(0,N,node[o].root,val,1);
bool tag;
if(k<=node[node[o].ls].siz+1) tag=check(node[node[o].ls].siz+1,node[o].siz), insert(node[o].ls,k,val,is||tag);
else tag=check(node[node[o].rs].siz+1,node[o].siz), insert(node[o].rs,k-node[node[o].ls].siz-1,val,is||tag);
if(!is&&tag) Rebuild(o);
}
int modify(int o,int pos,int delta){
int num;
if(pos==node[node[o].ls].siz+1) {
segin.update(0,N,node[o].root,node[o].val,-1),segin.dfs(node[o].cur),node[o].cur=0;
segin.update(0,N,node[o].root,delta,1),segin.update(0,N,node[o].cur,delta,1);
num=node[o].val,node[o].val=delta;
return num;
}
if(pos<=node[node[o].ls].siz) num=modify(node[o].ls,pos,delta);
else num=modify(node[o].rs,pos-node[node[o].ls].siz-1,delta);
segin.update(0,N,node[o].root,num,-1),segin.update(0,N,node[o].root,delta,1);
return num;
}
void Build(){
scanf("%d",&n),re.clear();
int tmp,x ;
for(int i=1;i<=n;++i)
scanf("%d",&tmp),newnode(x,tmp),re.push_back(x);
construct(0,re.size()-1,root);
}
void Get(int l,int r,int o,int L,int R){
if(l>R||r<L||l>r||!o)return;
if(l>=L&&r<=R) { seq[++count[0]]=node[o].root; return; }
int mid=node[node[o].ls].siz+l;
if(mid>=L&&mid<=R&&mid<=r) seq[++count[0]]=node[o].cur;
Get(l,mid-1,node[o].ls,L,R),Get(mid+1,r,node[o].rs,L,R);
}
int solve(int l,int r,int k){
if(l==r) return l;
int lsum=0;
for(int i=1;i<=count[0];++i) {
lsum+=segin.node[segin.node[seq[i]].ls].siz;
}
int mid=(l+r)>>1;
if(k>lsum)
{
for(int i=1;i<=count[0];++i) seq[i]=segin.node[seq[i]].rs;
return solve(mid+1,r,k-lsum);
}
else
{
for(int i=1;i<=count[0];++i)seq[i]=segin.node[seq[i]].ls;
return solve(l,mid,k);
}
}
void Insert(){
int a,b;
++n,scanf("%d%d",&a,&b),a^=lastans,b^=lastans,insert(root,a,b,0);
}
void Modify(){
int a,b;
scanf("%d%d",&a,&b),a^=lastans,b^=lastans,modify(root,a,b);
}
int Query(){
int L,R,k;
count[0]=0, scanf("%d%d%d",&L,&R,&k),L^=lastans,R^=lastans,k^=lastans;
if(L>R)swap(L,R);
Get(1,n,root,L,R);
return solve(0,N,k);
}
}BST;
int main(){
//setIO("input");
segin.init(), BST.Build();
char opt[10];
int q;
scanf("%d",&q);
while(q--){
scanf("%s",opt);
if(opt[0]=='I') BST.Insert();
if(opt[0]=='M') BST.Modify();
if(opt[0]=='Q') printf("%d\n",lastans=BST.Query());
}
return 0;
}

  

3065: 带插入区间K小值_树套树_替罪羊树_权值线段树的更多相关文章

  1. bzoj 3065: 带插入区间K小值 替罪羊树 && AC300

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Des ...

  2. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  3. BZOJ 3065 带插入区间K小值(sag套线段树)

    3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 4696  Solved: 1527[Submit][Status][Di ...

  4. 【BZOJ】3065: 带插入区间K小值

    http://www.lydsy.com/JudgeOnline/problem.php?id=3065 题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175 ...

  5. bzoj 3065: 带插入区间K小值(分块)

    Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它 ...

  6. BZOJ 3065 带插入区间K小值

    http://www.lydsy.com/JudgeOnline/problem.php?id=3065 思路:替罪羊树套权值线段树. 当替罪羊树某个子树大于某个比利(比例)时就暴力重构,本题时间复杂 ...

  7. BZOJ 3065 带插入区间K小值 (替罪羊树套线段树)

    毒瘤题.参考抄自博客:hzwer 第一次写替罪羊树,完全是照着题解写的,发现这玩意儿好强啊,不用旋转每次都重构还能nlognnlognnlogn. 还有外面二分和里面线段树的值域一样,那么r = mi ...

  8. 【学习笔记】浅析平衡树套线段树 & 带插入区间K小值

    常见的树套树 一般来说,在嵌套数据结构中,线段树多被作为外层结构使用. 但线段树毕竟是 静态 的结构,导致了一些不便. 下面是一个难以维护的例子: 带插入区间 \(k\) 小值问题 来源:Luogu ...

  9. [BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树

    刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值 ...

随机推荐

  1. 大量文件时使用ls

    有时一个目录下的文件实在太多, ls的时候就卡住了. 其实, 如果不加排序的话, 就可以迅速的显示文件. ls -f 解释: -f do not sort, enable -aU, disable - ...

  2. 解决局域网内无法IP访问IIS已发布的网站

    在IIS上发布的网站,本地可以访问,但是局域网内其他电脑却访问不了,原来是防火墙的问题,关闭它就可以访问了. 上面是我的简单操作 后来又百度了一下,发现有个更详细的操作:http://jingyan. ...

  3. 有关马氏距离和hinge loss的学习记录

    关于度量学习,之前没有看太多相关的文献.不过南京的周老师的一篇NIPS,确实把这个问题剖析得比较清楚. Mahalanobis距离一般表示为d=(x-y)TM(x-y),其中x和y是空间中两个样本点, ...

  4. (转载)Android引导界面实现

    Android引导界面实现 Android   2014-07-10 14:47:36 发布 您的评价:       4.0   收藏     3收藏 ViewPager类提供了多界面切换的新效果,是 ...

  5. swift语言点评十二-Subscripts

    Classes, structures, and enumerations can define subscripts, which are shortcuts for accessing the m ...

  6. Angualr+asp.net core webapi+efcore系列

    想着学习一门前端框架,WTF,看了又看,卧槽对于.Net程序员来说,还有什么比面向对象更香的呢,所以果断的选择了Angular.正好看各路大神以及官方文档想学习一下asp.net core,那就搞起吧 ...

  7. 路飞学城Python-Day16

  8. Ubuntu 如何进入系统文件/etc/profile修改内容

    转载:https://blog.csdn.net/cfq1491/article/details/81088117 /etc/profile 默认权限为 -rw-r--r-- 即只有root用户可以修 ...

  9. 紫书 习题 11-8 UVa 1663 (最大流求二分图最大基数匹配)

    很奇怪, 看到网上用的都是匈牙利算法求最大基数匹配 紫书上压根没讲这个算法, 而是用最大流求的. 难道是因为第一个人用匈牙利算法然后其他所有的博客都是看这个博客的吗? 很有可能-- 回归正题. 题目中 ...

  10. 紫书 习题8-12 UVa 1153(贪心)

    本来以为这道题是考不相交区间, 结果还专门复习了一遍前面写的, 然后发现这道题的区间是不是 固定的, 是在一个范围内"滑动的", 只要右端点不超过截止时间就ok. 然后我就先考虑有 ...