acwing265 P2234 营业额统计
#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e4;
struct node{
int key, val;
int l, r;
}fhq[maxn];
int cnt, root;
mt19937 rnd(233);
int newnode(int val){
cnt++;
fhq[cnt].key = rnd();
fhq[cnt].val = val;
fhq[cnt].l = fhq[cnt].r = 0;
return cnt;
}
void split(int now, int val, int &x, int &y){
if(!now) x = y = 0;
else{
if(fhq[now].val > val){
y = now;
split(fhq[now].l, val, x, fhq[now].l);
}else{
x = now;
split(fhq[now].r, val, fhq[now].r, y);
}
}
}
int merge(int x, int y){
if(!x || !y) return x+y;
else{
if(fhq[x].key < fhq[y].key){
fhq[x].r = merge(fhq[x].r, y);
return x;
}else{
fhq[y].l = merge(x, fhq[y].l);
return y;
}
}
}
int x, y, z1, z2, tmp1, tmp2;
void insert(int val){
split(root, val, x, y);
root = merge(merge(x, newnode(val)), y);
}
int ans;
void getans(int val){
split(root, val, x, y);
z1 = x;
z2 = y;
if(z1 && z2){
while(z1){
tmp2 = fhq[z1].val;
z1 = fhq[z1].r;
}
while(z2){
tmp1 = fhq[z2].val;
z2 = fhq[z2].l;
}
ans += min(abs(val - tmp1), abs(val - tmp2));
//cout<<"**"<<min(abs(val - tmp1), abs(val - tmp2))<<endl;
}else if(!z1){
while(z2){
tmp1 = fhq[z2].val;
z2 = fhq[z2].l;
//cout<<"debug"<<tmp1<<endl;
}
ans += abs(val - tmp1);
//cout<<"*"<<abs(val - tmp1)<<endl;
}
else if(!z2){
while(z1){
tmp2 = fhq[z1].val;
z1 = fhq[z1].r;
}
ans += abs(val - tmp2);
//cout<<"***"<<abs(val - tmp2)<<endl;
}
root = merge(x, y);
}
int main(){
int n, t;
ios::sync_with_stdio(false), cin.tie(0);
cin>>n; cin>>t; n--;
ans += t;
insert(t);
while(n--){
cin>>t;
getans(t);
insert(t);
}
cout<<ans;
return 0;
}
acwing950 P1486 郁闷的出纳员
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
struct node{
int key, val;
int l, r;
int size;
node(){
l = r = 0;
size = 0;
}
}fhq[maxn];
int cnt, root;
int add, mn;
mt19937 rnd(233);
int newnode(int val){
cnt++;
fhq[cnt].key = rnd();
fhq[cnt].val = val;
fhq[cnt].l = fhq[cnt].r = 0;
fhq[cnt].size = 1;
return cnt;
}
inline void update(int now){
fhq[now].size = fhq[fhq[now].l].size + fhq[fhq[now].r].size + 1;
}
void split(int now, int val, int &x, int &y){
if(!now) x=y=0;
else{
if(fhq[now].val <= val){
x = now;
split(fhq[now].r, val, fhq[now].r, y);
}else{
y = now;
split(fhq[now].l, val, x, fhq[now].l);
}
update(now);
}
}
int merge(int x, int y){
if(!x || !y) return x+y;
else{
if(fhq[x].key < fhq[y].key){
fhq[x].r = merge(fhq[x].r, y);
update(x);
return x;
}else{
fhq[y].l = merge(x, fhq[y].l);
update(y);
return y;
}
}
}
int getkth(int k){
if(k > fhq[root].size)
return -1;
int now = root;
int rank = fhq[now].size - k + 1;
while(now){
if(fhq[fhq[now].l].size + 1 == rank){
break;
}else if(fhq[fhq[now].l].size + 1 > rank){
now = fhq[now].l;
}else{
rank -= fhq[fhq[now].l].size + 1;
now = fhq[now].r;
}
}
return fhq[now].val + add;
}
int x, y, ans;
void del(int val){
split(root, val, x, y);
ans += fhq[x].size;
root = y;
}
void insert(int val){
split(root, val, x, y);
root = merge(x, merge(newnode(val), y));
}
int main(){
int n;
char c[10];
int t;
scanf("%d%d", &n, &mn);
while(n--){
scanf("%s %d", c, &t);
if(c[0] == 'I'){
if(t >= mn)
insert(t - add);
}
else if(c[0] == 'A') add += t;
else if(c[0] == 'S'){
add -= t;
del(mn - add - 1);
}
else if(c[0] == 'F') cout<<getkth(t)<<"
";
}
cout<<ans<<endl;
return 0;
}
acwing1063 P3224 永无乡
#include<bits/stdc++.h>
#define debug() cout<<"debug
"
using namespace std;
const int maxn = 1e5 + 5;
struct node{
int l, r;
int val, key;
int size;
node(){
l = r = size = 0;
}
}tree[maxn];
int cnt, root[maxn];
int w[maxn], idx[maxn];
int getf(int u){
return u == root[u]?u:root[u] = getf(root[u]);
}
mt19937 rnd(233);
int newnode(int val){
tree[++cnt].val = val;
tree[cnt].key = rnd();
tree[cnt].l = tree[cnt].r = 0;
tree[cnt].size = 1;
return cnt;
}
void update(int x){
tree[x].size = tree[tree[x].l].size + tree[tree[x].r].size + 1;
}
void split(int root, int val, int &x, int &y){
if(!root){
x = y = 0;
return ;
}else{
if(tree[root].val <= val){
x = root;
split(tree[root].r, val, tree[root].r, y);
}else{
y = root;
split(tree[root].l, val, x, tree[root].l);
}
update(root);
}
}
int merge(int x, int y){
if(!x || !y) return x+y;
else{
if(tree[x].key < tree[y].key){
tree[x].r = merge(tree[x].r, y);
update(x);
return x;
}else{
tree[y].l = merge(x, tree[y].l);
update(y);
return y;
}
}
}
int x, y;
void insert(int &root, int val){
split(root, w[val], x, y);
root = merge(x, merge(val, y));
//debug();
}
void dfs(int a, int &b){
if(!a) return;
dfs(tree[a].l, b);
dfs(tree[a].r, b);
tree[a].l = tree[a].r = 0;
//debug();
insert(b, a);
//debug();
}
//传结点编号
int Merge(int a, int b){
if(tree[a].size > tree[b].size) swap(a, b);
dfs(a, b);
return b;
}
int kth(int root, int k){
int now = root;
while(1){
if(k == tree[tree[now].l].size + 1) return now;
else if(k < tree[tree[now].l].size + 1) now = tree[now].l;
else{
k -= tree[tree[now].l].size + 1;
now = tree[now].r;
}
}
}
int main(){
int n, m, Q, x, k;
char q[2];
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", w+i);
root[i] = newnode(w[i]); //以结点权值建点,root[i]第i个treap根结点编号
}
int u, v, fa;
while(m--){
scanf("%d%d", &u, &v);
if(getf(u) == getf(v)) continue;
fa = Merge(root[u], root[v]);
root[getf(u)] = root[getf(v)] = fa;
}
scanf("%d", &Q);
while(Q--){
scanf("%s%d%d", q, &x, &k);
if(q[0] == 'Q'){
if(tree[getf(x)].size < k)
printf("-1
");
else
printf("%d
", kth(getf(x), k));
}else if(q[0] == 'B'){
if(getf(x) == getf(k)) continue;
fa = Merge(root[x], root[k]);
root[getf(x)] = root[getf(k)] = fa;
}
}
return 0;
}
T1脑瘫题 求前驱后缀其实set也能做
T2求Kth 基操,注意新加入的员工插入时薪水-add即可(因为是全局增减量
T3 求Kth&启发式合并treap (刚写的时候因为弄混权值和编号卡了好久……(还把split写炸了QAQ
启发式合并:把小treap暴力拆了插到大treap里…(i了i了