4923: [Lydsy1706 month contest] K small value query balanced tree non-rotation Treap

The topic of international practice:

This kind of maintenance sorting sequence, the problem of strictly greater than the operation is very routine...
Let's discuss it according to [0,k], (k,2k], (2k,inf) classification That's good.
Obviously the first interval will not change, the second interval will be translated into the first interval, and the relative size of the third interval will not change.
So we directly demolish the second interval and reconstruct it . , you can insert the first interval one by one. Because each time is at least halved, each element will only be reconstructed log times, with a complexity of nlog^2n.
This operation of separating intervals according to the value range is non-rotating Treap is the easiest to implement...
However, there is still a problem with writing a non-rotating treap for the first time. Note that its insertion is achieved by splitting according to the value range, creating new points, and then merging twice. Directly The insertion complexity is wrong.
In addition, the two treaps cannot be merged directly when the interval value ranges overlap...
The version I wrote to determine the size seems to have the wrong complexity (not as fast as violence?), so I had to pre-generate the fix value.

Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 const int maxn=1e5+1e2;
 5 
 6 typedef std::pair<int,int> pii;
 7 __inline pii mp(const int &x,const int &y) { return std::make_pair(x,y); }
 8 
 9 int seq[maxn],sql;
10 int stk[maxn],top;
11 
12 struct Treap {
13     int lson[maxn],rson[maxn],lazy[maxn],val[maxn],siz[maxn],fix[maxn],cnt;
14     
15     inline void init(int n) {
16         for(int i=1;i<=n;i++) fix[i] = i;
17         std::random_shuffle(fix+1,fix+1+n);
18     }
19     inline void apply(int pos,int x) {
20         if(pos) lazy[pos] += x , val[pos] -= x;
21     }
22     inline void push(int pos) {
23         if( lazy[pos] ) apply(lson[pos],lazy[pos]) , apply(rson[pos],lazy[pos]) , lazy[pos] = 0;
24     }
25     inline void maintain(int pos) {
26         siz[pos] = siz[lson[pos]] + siz[rson[pos]] + 1;
27     }
28 
29     inline pii split(int pos,int dv) { // left is <= , right is > .
30         if( !pos ) return mp(0,0);
31         push(pos);
32         if(  dv < val[pos] ) {
33             pii spl = split(lson[pos],dv);
34             lson[pos] = spl.second , maintain(pos);
35             return mp(spl.first,pos);
36         } else {
37             pii spr = split(rson[pos],dv);
38             rson[pos] = spr.first , maintain(pos);
39             return mp(pos,spr.second);
40         }
41     }
42     inline int merge(int x,int y) {
43         if( !x || !y ) return x | y;
44         push(x) , push(y);
45         if( val[x] > val[y] ) std::swap(x,y);
46         if( fix[x] > fix[y] ) { // siz[x] is bigger .
47             lson[y] = merge(lson[y],x) , maintain(y);
48             return y;
49         } else {
50             rson[x] = merge(rson[x],y) , maintain(x);
51             return x;
52         }
53     }
54     inline void dfs(int pos) {
55         if( !pos ) return;
56         seq[++sql] = val[pos] , push(pos);
57         dfs(lson[pos]) , dfs(rson[pos]);
58         lson[pos] = rson[pos] = siz[pos] = 0 , stk[++top] = pos;
59     }
60     inline int kth(int pos,int k) { // return the kth value .
61         if( k == siz[lson[pos]] + 1 ) return val[pos];
62         return push(pos) , k <= siz[lson[pos]] ? kth(lson[pos],k) : kth(rson[pos],k-siz[lson[pos]]-1);
63     }
64     inline void insert(int &root,int x) {
65         val[++cnt] = x , siz[cnt] = 1;
66         pii sp = split(root,x);
67         root = merge(sp.first,cnt) , root = merge(root,sp.second);
68     }
69     inline void reinsert(int &root,int x) {
70         int cur = stk[top--];
71         val[cur] = x , siz[cur] = 1;
72         pii sp = split(root,x);
73         root = merge(sp.first,cur) , root = merge(root,sp.second);
74     }
75     
76 }tp;
77 
78 int main() {
79     static int n,m,root,rtl,rtm,rtr;
80     scanf("%d%d",&n,&m) , tp.init(n);
81     for(int i=1,t;i<=n;i++) scanf("%d",&t) , tp.insert(root,t);
82     for(int i=1,o,x;i<=m;i++) {
83         scanf("%d%d",&o,&x);
84         if( o == 1 ) printf("%d\n",tp.kth(root,x));
85         else if( o == 2 ) {
86             pii sp = tp.split(root,x);
87             rtl = sp.first , sp = tp.split(sp.second,x<<1);
88             rtm = sp.first , rtr = sp.second;
89             sql = 0 , tp.dfs(rtm) , tp.apply(rtr,x);
90             for(int i=1;i<=sql;i++) tp.reinsert(rtl,seq[i]-x);
91             root = tp.merge(rtl,rtr);
92         }
93     }
94     return 0;
95 }
View Code



Thupc rejected! I'm sorry, yzy is a big deal! (Immediate use of this sample, the refusal of the capital, the end of the consciousness) If you stay as

it is, you should always have a state of self-
reliance . Unnecessary Liberation Hope 崭 New 梦imagination You just have to draw as much as you can .











Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325302812&siteId=291194637