P3850 [TJOI2007] 书架

P3850 [TJOI2007] 书架

[TJOI2007] 书架

题目描述

Knuth 先生家里有个精致的书架,书架上有 N 本书,如今他想学到更多的知识,于是又买来了 M 本不同的新书。现在他要把新买的书依次插入到书架中,他已经把每本书要插入的位置标记好了,并且相应的将它们放好。由于 Knuth 年龄已大,过几天他已经记不清某些位置上放的到底是什么书了,请问你能帮助他吗?

对于 100% 的数据,1N200, 1M105, 1Q104. 保证输入合法

Solution:

最近线段树写吐了捏,来写平衡树捏,平衡树好写捏。

其实我没太搞懂这是怎么评到紫的,我们只需要按照题面维护一颗平衡树,然后对于每个插入操作 (x,k),将 FHQ-Treap 的前 k 个节点splite出来,然后再按照 (L,x,R) 的顺序 merge 回去。
查询也是直接 splite 然后输出,再 merge

感觉没什么难的,几乎没有任何思维难度。

感觉这个甚至比平衡树模板简单

点击此处与妙妙思维平衡题一决高下

Code:

#include<bits/stdc++.h>
const int N=1.1e5+5;
int rd(){return rand()*rand()+1;}
using namespace std;
//FHQ-Treap:
int n,m,cnt,rt,q;
struct FHQ_Treap{
struct Tree{
int ls,rs,val,siz,rnd;
}t[N];
void pushup(int x){t[x].siz=t[t[x].ls].siz+t[t[x].rs].siz+1;}
int Node()
{
cnt++;
t[cnt]={0,0,cnt,1,rd()};
return cnt;
}
void splite(int x,int &a,int &b,int k)
{
if(!x){a=b=0;return;}
int tmp=t[t[x].ls].siz+1;
if(tmp<=k)
{
a=x;
splite(t[x].rs,t[a].rs,b,k-tmp);
pushup(a);
}
else
{
b=x;
splite(t[x].ls,a,t[b].ls,k);
pushup(b);
}
}
int merge(int x,int y)
{
if(!x||!y)return x|y;
if(t[x].rnd<t[y].rnd)
{
t[x].rs=merge(t[x].rs,y);
pushup(x);
return x;
}
else
{
t[y].ls=merge(x,t[y].ls);
pushup(y);
return y;
}
}
}T;
string s[N];
void work()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i];
rt=T.merge(rt,T.Node());
}
cin>>m;
for(int i=1,k,a,b;i<=m;i++)
{
cin>>s[T.Node()];
cin>>k;
T.splite(rt,a,b,k);
rt=T.merge(T.merge(a,cnt),b);
}
cin>>q;
for(int i=1,k,a,b,c;i<=q;i++)
{
cin>>k;
T.splite(rt,a,b,k+1);
T.splite(a,a,c,k);
cout<<s[T.t[c].val]<<"\n";
rt=T.merge(T.merge(a,c),b);
}
}
int main()
{
//freopen("P3850.in","r",stdin);freopen("P3850.out","w",stdout);
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
work();
return 0;
}
posted @   liuboom  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示