思路:该题目要求在log(n)时间内进行插入,删除,求后继操作,可以使用平衡树解决,由于不用求名次或者取k大,所以可以和使用stl set来解决,可以存在相同的数,所以要用multiset.
代码如下
- #include <set>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- int main()
- {
- int i,j,k,t;
- int n, q, y;
- scanf("%d", &t);
- for(k = 1; k <= t; k++)
- {
- printf("Case %d:/n", k);
- multiset<int> a;
- scanf("%d%d%d", &n, &q, &y);
- for(i = 0; i < n; i++)
- {
- scanf("%d", &j);
- a.insert(j);
- }
- set<int>::iterator low;
- for(i = 0; i < q; i++)
- {
- scanf("%d", &j);
- low = a.lower_bound(j);
- //printf(" %d %d/n", j, *low);
- if(low == a.end() || *low-j > y) puts("-1");
- else
- {
- printf("%d/n", *low);
- a.erase(low);
- }
- }
- }
- }
为了练习的目的,再次用SBT写了一遍,思路相同
- #include <algorithm>
- using namespace std;
- struct sbt_node
- {
- int key,sz;
- sbt_node *lc, *rc;
- sbt_node(int x, int y);
- }NIL=sbt_node(0,0),*nil=&NIL;
- sbt_node::sbt_node(int x, int y=1)
- {
- key=x,sz=y;
- lc=rc=nil;
- }
- typedef sbt_node *node;
- node root;
- void right_rotate(node &y)
- {
- node x = y->lc;
- y->lc = x->rc;
- x->rc = y;
- x->sz = y->sz;
- y->sz = y->lc->sz + y->rc->sz +1;
- y = x;
- }
- void left_rotate(node &x)
- {
- node y = x->rc;
- x->rc = y->lc;
- y->lc = x;
- y->sz = x->sz;
- x->sz = x->lc->sz + x->rc->sz +1;
- x = y;
- }
- void maintain(node &t, bool right_high)
- {
- if(!right_high)
- {
- if(t->lc==nil)return;
- if(t->lc->lc->sz > t->rc->sz)
- {
- right_rotate(t);
- }
- else if(t->lc->rc->sz > t->rc->sz)
- {
- left_rotate(t->lc);
- right_rotate(t);
- }
- else return;
- }
- else
- {
- if(t->rc==nil)return;
- if(t->rc->rc->sz > t->lc->sz)
- {
- left_rotate(t);
- }
- else if(t->rc->lc->sz > t->lc->sz)
- {
- right_rotate(t->rc);
- left_rotate(t);
- }
- else return;
- }
- maintain(t->lc, 0);
- maintain(t->rc, 1);
- maintain(t, 0);
- maintain(t, 1);
- }
- void insert(node &t, int x)
- {
- if(t==nil)
- {
- t = new sbt_node(x);
- }
- else
- {
- t->sz++;
- if(x < t->key) insert(t->lc, x);
- else insert(t->rc, x);
- }
- maintain(t, x >= t->key);
- }
- void del(node &t, int x)
- {
- if(t==nil)return;
- t->sz--;
- if(x < t->key) del(t->lc, x);
- else if(x > t->key) del(t->rc, x);
- if(x == t->key)
- {
- if(t->lc==nil)
- {
- t = t->rc;
- }
- else if(t->rc==nil)
- {
- t = t->lc;
- }
- else
- {
- node tmp=t->rc;
- while(tmp->lc != nil)tmp = tmp->lc;
- t->key = tmp->key;
- del(t->rc, tmp->key);
- }
- }
- }
- int succ(node t, int x)
- {
- if(t==nil)return -1;
- if(x == t->key) return x;
- else if(x > t->key) return succ(t->rc, x);
- else
- {
- int tmp=succ(t->lc,x);
- if(tmp == -1)
- {
- return t->key;
- }
- else return tmp;
- }
- }
- void print2(node t)
- {
- if(t==nil)return;
- putchar('(');
- print2(t->lc);
- printf("size[%d]=%d/t", t->key, t->sz);
- print2(t->rc);
- putchar(')');
- }
- void print(node t)
- {
- print2(t);
- puts("");
- }
- /*
- 2
- 10 10 10
- 7 5 3 2 1 2 3 5 7 9
- 1 5 5 5 5 5 5 5 5 5
- 10 10 10
- 1 2 3 4 5 6 7 8 9 10
- 1 2 3 4 3 3 3 9 9 9
- */
- int main()
- {
- int i, j, k, t;
- int n, q, y;
- scanf("%d", &t);
- for(k = 1; k <= t; k++)
- {
- root = nil;
- scanf("%d%d%d", &n, &q, &y);
- for(i = 0; i < n; i++)
- {
- scanf("%d", &j);
- insert(root, j);
- }
- printf("Case %d:/n", k);
- for(i = 0; i < q; i++)
- {
- scanf("%d", &j);
- int tmp = succ(root, j);
- if(tmp == -1 || tmp-j>y) puts("-1");
- else
- {
- del(root, tmp);
- printf("%d/n", tmp);
- }
- //print(root);
- }
- }
- return 0;
- }