很裸的一道平衡树的题。
唯一要思考的一点就是需要维护一个当前树的种类,如果当前进来的与树的种类相同的话,就直接插入,否则就找一个最接近的的值并把那个值删除,并记录答案就行了。
代码:
#include<cstdio>
#include<cstring>
#define L ch[p][0]
#define R ch[p][1]
#define LL ch[ch[p][0]][0]
#define RR ch[ch[p][1]][1]
#define LR ch[ch[p][0]][1]
#define RL ch[ch[p][1]][0]
using namespace std;
const int inf = 0x3f3f3f3f;
const int mo = 1000000;
const int maxn = 100000;
int ch[maxn][2];
int sz[maxn],val[maxn];
int min,p = 0;
int top = 0,cnt = 0,ret;
int n,kind,root,ans = 0;
void init()
{
freopen("bzoj1208.in","r",stdin);
freopen("bzoj1208.out","w",stdout);
}
int del(int &p,int key)
{
sz[p]--;
if((val[p] == key) || (key < val[p] && !ch[p][0]) || (key > val[p] && !ch[p][1]))
{
int res = val[p];
if(!ch[p][0] || !ch[p][1])p = ch[p][0] + ch[p][1];
else val[p] = del(ch[p][0],val[p] + 1);
return res;
}
else
{
if(key < val[p])return del(ch[p][0],key);
else return del(ch[p][1],key);
}
}
void find(int &p,int key)
{
if(!p)return;
if(key > val[p])
{
if(min >= key - val[p])min = key - val[p],ret = p;
}
else if(min > val[p] - key)min = val[p] - key,ret = p;
find(ch[p][key > val[p]],key);
}
void Rotate(int &p,int f)
{
int k = ch[p][!f];
ch[p][!f] = ch[k][f];
ch[k][f] = p;
sz[k] = sz[p];
sz[p] = sz[L] + sz[R] + 1;
p = k;
}
void maintain(int &p,bool flag)
{
if(p == 0)return;
if(!flag)
{
if(sz[LL] > sz[R])Rotate(p,1);
else if(sz[LR] > sz[R])Rotate(L,0),Rotate(p,1);
else return;
}
else
{
if(sz[RR] > sz[L])Rotate(p,0);
else if(sz[RL] > sz[L])Rotate(R,1),Rotate(p,0);
else return;
}
maintain(L,false);
maintain(R,true);
maintain(p,false);
maintain(p,true);
}
void insert(int &p,int key)
{
if(p == 0)
{
p = ++top;
ch[p][0] = ch[p][1] = 0;
sz[p] = 1;
val[p] = key;
return;
}
sz[p]++;
if(key < val[p])insert(ch[p][0],key);
else insert(ch[p][1],key);
maintain(p,!(key < val[p]));
}
void readdata()
{
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(root == 0)
{
kind = a;
insert(root,b);
cnt++;
}
else
{
if(!cnt || a == kind)kind = a,insert(root,b),cnt++;
else
{
min = inf;
find(root,b);
del(root,val[ret]);
--cnt;
ans = (ans + min) % mo;
}
}
}
printf("%d",ans);
}
int main()
{
init();
readdata();
return 0;
}