P2286 [HNOI2004]宠物收养场

忘记取模惹 $\text{qwq}$ 。

比较适合做一道平衡树的入门练习题。

首先要把冗长的题目理解,然后转换为我们可做的。

建立两棵平衡树,每次在对方平衡树里查找当前询问的前驱后继后统计答案即可。

不要忘记取模!!!

因为有 $1\leq a\leq 2^{31}-1$ ,所以理论上不会爆 int

AC Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<iomanip>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define gh() getchar()
#define re register
typedef long long ll;
template<class T>
inline void read(T &x)
{
x=0;
char ch=gh(),t=0;
while(ch<'0'||ch>'9') t|=ch=='-',ch=gh();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=gh();
if(t) x=-x;
}
template<class T,class ...T1>
inline void read(T &x,T1 &...x1)
{
read(x),read(x1...);
}
template<class T>
inline void write(T x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
template<class T>
inline bool checkMax(T &x,T &y)
{
return x<y?x=y,1:0;
}
template<class T>
inline bool checkMin(T &x,T &y)
{
return x>y?x=y,1:0;
}
const int MAXN=8e4+10;
const int INF=0x7f7f7f7f;
const int Mod=1e6;
int N;
struct B_T
{
int Idx=0,Rt=0;
int x,y,z;
struct Fhq
{
int val,rd,siz,chi[2];
}Tr[MAXN];
#define ls(p) Tr[p].chi[0]
#define rs(p) Tr[p].chi[1]
inline int newNode(int v)
{
Tr[++Idx]=(Fhq){v,rand(),1};
return Idx;
}
inline void upDate(int p)
{
Tr[p].siz=Tr[ls(p)].siz+Tr[rs(p)].siz+1;
}
inline void split(int p,int k,int &u,int &v)
{
if(!p) u=v=0;
else
{
if(Tr[p].val<=k) u=p,split(rs(u),k,rs(u),v);
else v=p,split(ls(v),k,u,ls(v));
upDate(p);
}
}
inline int merge(int u,int v)
{
if(!u||!v) return u+v;
if(Tr[u].rd<Tr[v].rd)
{
rs(u)=merge(rs(u),v);
upDate(u);return u;
}
else
{
ls(v)=merge(u,ls(v));
upDate(v);return v;
}
}
inline void insert(int v)
{
x=y=0;
split(Rt,v,x,y);
Rt=merge(merge(x,newNode(v)),y);
}
inline void del(int v)
{
x=y=z=0;
split(Rt,v,x,z),split(x,v-1,x,y);
y=merge(ls(y),rs(y));
Rt=merge(merge(x,y),z);
}
inline int kth(int u,int k)
{
while(1)
{
if(k<=Tr[ls(u)].siz) u=ls(u);
else if(k==Tr[ls(u)].siz+1) return u;
else k-=Tr[ls(u)].siz+1,u=rs(u);
}
}
inline int pre(int v)
{
x=y=0;
split(Rt,v,x,y);
if(!x) return -INF;
int res=Tr[kth(x,Tr[x].siz)].val;
Rt=merge(x,y);
return res;
}
inline int nxt(int v)
{
x=y=0;
split(Rt,v-1,x,y);
if(!y) return INF;
int res=Tr[kth(y,1)].val;
Rt=merge(x,y);
return res;
}
}Per,Pet;
int cntPer,cntPet,ans;
int main()
{
// freopen("fhq-treap.in","r",stdin);
// freopen("fhq-treap.out","w",stdout);
srand(time(NULL));
read(N);
for(int opt,x;N--;)
{
read(opt,x);
if(opt==0)
{
if(cntPer)
{
int pre=Per.pre(x),nxt=Per.nxt(x);
if(std::abs(x-pre)==std::abs(nxt-x)) Per.del(pre);
else (std::abs(x-pre))>(std::abs(nxt-x))?Per.del(nxt):Per.del(pre);
--cntPer;
ans=(ans+std::min(std::abs(nxt-x),std::abs(x-pre)))%Mod;
// printf("%d %d\n",pre,nxt);
}
else
{
++cntPet;
Pet.insert(x);
}
}
else
{
if(cntPet)
{
int pre=Pet.pre(x),nxt=Pet.nxt(x);
if(std::abs(x-pre)==std::abs(nxt-x)) Pet.del(pre);
else (std::abs(x-pre))>(std::abs(nxt-x))?Pet.del(nxt):Pet.del(pre);
--cntPet;
ans=(ans+std::min(std::abs(nxt-x),std::abs(x-pre)))%Mod;
// printf("%d %d\n",pre,nxt);
}
else
{
++cntPer;
Per.insert(x);
}
}
// printf("%d %d\n",cntPer,cntPet);
}
write(ans);
return 0;
}
/*
5
0 2
0 4
1 3
1 2
1 5
*/