Bzoj 3196 binary Balance Tree treap (line segment tree treap)

Source: Internet
Author: User

Question:

Write a data structure, which can:

1. query the ranking of K in the interval.

2. query the value of the row named K in the interval.

3. modify a value.

4. Find the precursor of K in the interval.

5. Find the successor of K in the interval.


Thought: I thought there was a magical data structure that could only be known by the gods to maintain it. After asking someone else, I found that it was just a tree. It is said that everything can be set. I can only build a line segment tree with treap.

This is also the first time I have written a tree set. I am a little happy that I still have 1A.

When writing a tree cover tree, you must be sure that you are familiar with the two trees. with a small amount of fine thinking, you can complete the tree cover. (I am just a weak scum. Please be careful. d)

Implementation: The first layer is the line segment tree and the second layer is the treap. Because the nodes of each line segment tree represent the actual segments, A treap can be connected to the nodes of each line segment tree to maintain the segments) obtain the information of this interval within the specified time range.

Consider the first operation: considering the working principle of the Line Segment tree, the entire segment is directly operated on the treap in this interval, and then the result is returned. For ininteger intervals, recursion solves the left half and right half, and then adds up to return.

The second operation: For a whole range, you can directly find the maximum K of the range on the treap, but there is no way to do anything about the partial range. So there is no way to search for this value in the second logn layer. For the binary mid value, find the ranking of this value in the interval, which obviously satisfies the binary nature. We need to discuss the boundary conditions of this question.

The third operation: recursively modify down. If a node does not pass through a line segment tree, subtract the value of the original position from the treap next to the node, and then add the value of the position.

The last two operations: For an entire interval, the system directly returns the precursor returned by the treap, and then the successor. Returns the left half part, right half part, minimum or maximum value recursively.


Code:


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 50010#define INF 1e9#define LEFT (pos << 1)#define RIGHT (pos << 1|1)#define SIZE(x) ((x == NULL) ? 0:x->size)using namespace std;struct Complex{int val,cnt,size,random;Complex *son[2];Complex() {son[0] = son[1] = NULL;cnt = size = 1;random = rand();}int Compare(int x) {if(x == val)return -1;return x > val;}void Maintain() {size = cnt;if(son[0] != NULL)size += son[0]->size;if(son[1] != NULL)size += son[1]->size;}};int cnt,asks;int src[MAX];Complex *tree[MAX << 2];void Pretreatment();void BuildTree(int l,int r,int pos);int GetRank(int l,int r,int x,int y,int pos,int k);int GetKth(int x,int y,int pos,int k);void Modify(int l,int r,int aim,int pos,int c);int FindPred(int l,int r,int x,int y,int pos,int k);int FindSucc(int l,int r,int x,int y,int pos,int k); inline void Rotate(Complex *&a,bool dir);void Insert(Complex *&a,int x);void Delete(Complex *&a,int x);int GetRank(Complex *a,int k);int FindPred(Complex *a,int x);int FindSucc(Complex *a,int x);int main(){Pretreatment();cin >> cnt >> asks;for(int i = 1;i <= cnt; ++i)scanf("%d",&src[i]);BuildTree(1,cnt,1);for(int flag,i = 1;i <= asks; ++i) {scanf("%d",&flag);int x,y,z;if(flag == 1) {scanf("%d%d%d",&x,&y,&z);printf("%d\n",GetRank(1,cnt,x,y,1,z) + 1);}if(flag == 2) {scanf("%d%d%d",&x,&y,&z);printf("%d\n",GetKth(x,y,1,z));}if(flag == 3) {scanf("%d%d",&x,&y);Modify(1,cnt,x,1,y);src[x] = y;}if(flag == 4) {scanf("%d%d%d",&x,&y,&z);printf("%d\n",FindPred(1,cnt,x,y,1,z));}if(flag == 5) {scanf("%d%d%d",&x,&y,&z);printf("%d\n",FindSucc(1,cnt,x,y,1,z));}}return 0;}void Pretreatment(){memset(tree,NULL,sizeof(tree));}void BuildTree(int l,int r,int pos){for(int i = l;i <= r; ++i)Insert(tree[pos],src[i]);if(l == r)return ;int mid = (l + r) >> 1;BuildTree(l,mid,LEFT);BuildTree(mid + 1,r,RIGHT);}int GetRank(int l,int r,int x,int y,int pos,int k){if(l == x && y == r)return GetRank(tree[pos],k);int mid = (l + r) >> 1;if(y <= mid)return GetRank(l,mid,x,y,LEFT,k);if(x > mid)return GetRank(mid + 1,r,x,y,RIGHT,k);int left = GetRank(l,mid,x,mid,LEFT,k);int right = GetRank(mid + 1,r,mid + 1,y,RIGHT,k);return left + right;}int GetKth(int x,int y,int pos,int k){int L = 0,R = INF,re;while(L <= R) {int mid = (L + R) >> 1;int temp = GetRank(1,cnt,x,y,1,mid);if(temp < k)L = mid + 1;elseR = mid - 1;}int temp = GetRank(1,cnt,x,y,1,L);if(temp >= k)L = FindPred(1,cnt,x,y,1,L);return L;}void Modify(int l,int r,int aim,int pos,int c){Delete(tree[pos],src[aim]);Insert(tree[pos],c);if(l == r)return ;int mid = (l + r) >> 1;if(aim <= mid)Modify(l,mid,aim,LEFT,c);elseModify(mid + 1,r,aim,RIGHT,c);}int FindPred(int l,int r,int x,int y,int pos,int k){if(l == x && y == r)return FindPred(tree[pos],k);int mid = (l + r) >> 1;if(y <= mid)return FindPred(l,mid,x,y,LEFT,k);if(x > mid)return FindPred(mid + 1,r,x,y,RIGHT,k);int left = FindPred(l,mid,x,mid,LEFT,k);int right = FindPred(mid + 1,r,mid + 1,y,RIGHT,k);return max(left,right);}int FindSucc(int l,int r,int x,int y,int pos,int k){if(l == x && y == r)return FindSucc(tree[pos],k);int mid = (l + r) >> 1;if(y <= mid)return FindSucc(l,mid,x,y,LEFT,k);if(x > mid)return FindSucc(mid + 1,r,x,y,RIGHT,k);int left = FindSucc(l,mid,x,mid,LEFT,k);int right = FindSucc(mid + 1,r,mid + 1,y,RIGHT,k);return min(left,right);}////////////////////////////////Treap///////////////////////////inline void Rotate(Complex *&a,bool dir){Complex *k = a->son[!dir];a->son[!dir] = k->son[dir];k->son[dir] = a;a->Maintain(),k->Maintain();a = k;}void Insert(Complex *&a,int x){if(a == NULL) {a = new Complex();a->val = x;return ;}int dir = a->Compare(x);if(dir == -1)a->cnt++;else {Insert(a->son[dir],x);if(a->son[dir]->random > a->random)Rotate(a,!dir);}a->Maintain();}void Delete(Complex *&a,int x){int dir = a->Compare(x);if(dir != -1)Delete(a->son[dir],x);else {if(a->cnt > 1)a->cnt--;else {if(a->son[0] == NULL)a = a->son[1];else if(a->son[1] == NULL)a = a->son[0];else {bool _dir = (a->son[0]->random > a->son[1]->random);Rotate(a,_dir);Delete(a->son[_dir],x);}}}if(a != NULL)a->Maintain();}int GetRank(Complex *a,int k){if(a == NULL)return 0;if(k <= a->val)return GetRank(a->son[0],k);return SIZE(a->son[0]) + a->cnt + GetRank(a->son[1],k);}int FindPred(Complex *a,int x){if(a == NULL)return -INF;if(a->val >= x)return FindPred(a->son[0],x);return max(a->val,FindPred(a->son[1],x));}int FindSucc(Complex *a,int x){if(a == NULL)return INF;if(a->val <= x)return FindSucc(a->son[1],x);return min(a->val,FindSucc(a->son[0],x));}


Bzoj 3196 binary Balance Tree treap (line segment tree treap)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.