splay参考:http://blog.csdn.net/acm_fighting/article/details/52331833
Splay中有一些常用的操作和一些很容易犯的bug
先来记录一下容易写错的地方
新建结点(或者连续一段,特指在key_value的位置插入和删除)或者删除结点(或者连续一段)的时候需要pushup(ch[root][1]),pushup(root)
申请一个新的结点的时候注意更新与这个点所有相关的变量,比如是维护最小值,不仅要更新val[now],还要更新minv[now]
如果有区间加的时候,你需要查询Splay上某个点的值,你不能直接输出val[now],应该先把这个点旋转到根
如果需要知道某个值在Splay中的位置,可以用一个map映射
调用get_kth,get_min,get_max这些函数时,要把调用的这个点旋转到根
插入的时候要进行旋转,这样才能保证时间复杂度logn
题目:https://vjudge.net/problem/SGU-311
博客:http://blog.csdn.net/pro_space/article/details/47008961
题意:一个商店,有两种操作:(1)ARRIVE n c表示进货n个,每个c元。(2)BUY n t表示一个买货的人要买n个,一共拿了t元钱。如果现在店里的货的数量大于等于n且最便宜的n个的价格小于等于t则将最便宜的卖给他。否则不卖。
思路:离线的线段树,我们以价格作为结点,然后离散化,好久没做,注意的是优先处理最小的n个
线段树代码:https://vjudge.net/solution/3657190
只能说又写炸了.
#include<bits/stdc++.h>
using namespace std;
#define MP make_pair
#define N 100005
#define LL long long
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define md ((ll+rr)>>1)
#define ls (i<<1)
#define rs ((i<<1)|1)
#define lson ls,ll,md
#define rson rs,md+1,rr
struct Q{
char op[10];
int num;
LL c;
}q[N];
LL san[N];
LL sum[N<<2];
int num[N<<2],lazy[N<<2],L[N<<2],R[N<<2];
void up(int i){
sum[i]=sum[ls]+sum[rs];
num[i]=num[ls]+num[rs];
}
void down(int i){
if(lazy[i]){
lazy[ls]=lazy[rs]=lazy[i];
sum[ls]=sum[rs]=0;
num[ls]=num[rs]=0;
lazy[i]=0;
return;
}
}
void build(int i,int ll,int rr){
L[i]=ll;R[i]=rr;
lazy[i]=0;
if(ll==rr){
lazy[i]=0;
sum[i]=num[i]=0;return;
}
build(lson),build(rson);
up(i);
}
void add(int i,int cnt,LL c){
if(san[L[i]]==c&&san[R[i]]==c){
sum[i]+=c*cnt;
num[i]+=cnt;return;
}
down(i);
if(c<=san[R[ls]])add(ls,cnt,c);
else add(rs,cnt,c);
up(i);
}
LL query(int i,int cnt){
if(L[i]==R[i]){return 1LL*cnt*san[L[i]];}
down(i);
if(num[ls]>=cnt)return query(ls,cnt);
else return sum[ls]+query(rs,cnt-num[ls]);
up(i);
}
void clear(int i,int cnt){
if(L[i]==R[i]){
num[i]-=cnt;
sum[i]=num[i]*L[i];
return;
}
down(i);
if(num[ls]>=cnt)clear(ls,cnt);
else {
clear(rs,cnt-num[ls]);
lazy[ls]=1;
sum[ls]=num[ls]=0;
}
up(i);
}
void show(int i){
if(L[i]==R[i]){
printf("%d ",sum[i]);
return;
}
show(ls);show(rs);
}
int main(){
int n=1;
int tot=0;
while(~scanf("%s%d%lld",q[n].op,&q[n].num,&q[n].c)){
san[++tot]=q[n].c;
++n;
}n--;
sort(san+1,san+1+tot);
tot=unique(san+1,san+1+tot)-san-1;
build(1,1,tot);
for(int i=1;i<=n;++i){
if(q[i].op[0]=='A'){
add(1,q[i].num,q[i].c);
}
else {
if(query(1,q[i].num)>q[i].c)puts("UNHAPPY");
else {
clear(1,q[i].num);puts("HAPPY");
}
}
//show(1);puts("");
}
}
splay代码: