[关闭]
@yang12138 2018-10-27T00:58:42.000000Z 字数 12156 阅读 1178

板子


KD树

  1. //二维kd树,询问给定点到已知点集的最短距离,k维同理
  2. //基于欧几里得距离,基于曼哈顿距离同理
  3. const int N=2e5+10;
  4. struct Point{
  5. ll x[2];
  6. Point(){
  7. memset(x,0,sizeof(x));
  8. }
  9. };
  10. ll dis(const Point& a,const Point& b){
  11. ll ans=0;
  12. for(int i=0;i<2;i++) ans+=1LL*(a.x[i]-b.x[i])*(a.x[i]-b.x[i]);
  13. return ans;
  14. }
  15. int DIM;
  16. bool cmp(const Point& a,const Point& b){
  17. return a.x[DIM]<b.x[DIM];
  18. }
  19. ll pw(ll a){return a*a;}
  20. struct Node{
  21. Point p;
  22. int dim;
  23. Node *lson,*rson;
  24. Node(){
  25. lson = rson = NULL;
  26. }
  27. };
  28. Node* newNode(){
  29. return new Node;
  30. }
  31. void build(Node* &root,vector<Point>vec,int dep){
  32. if(!vec.size()){
  33. root=NULL;
  34. return ;
  35. }
  36. root = newNode();
  37. DIM=root->dim=dep;
  38. sort(vec.begin(),vec.end(),cmp);
  39. int sz = (int)vec.size();
  40. root->p = vec[sz/2];
  41. vector<Point>lvec,rvec;
  42. for(int i=0;i<=sz/2-1;i++) lvec.push_back(vec[i]);
  43. for(int i=sz/2+1;i<sz;i++) rvec.push_back(vec[i]);
  44. build(root->lson,lvec,dep^1);
  45. build(root->rson,rvec,dep^1);
  46. }
  47. void add(Node* &root,const Point& tar,int dep){
  48. if(root==NULL){
  49. root=newNode();
  50. root->p=tar,root->dim=dep;
  51. return ;
  52. }
  53. if(tar.x[dep]<=root->p.x[dep])
  54. add(root->lson,tar,dep^1);
  55. else add(root->rson,tar,dep^1);
  56. }
  57. void search(const Node* root,const Point& tar,ll& min_dis){
  58. if(root==NULL) return ;
  59. if(dis(tar,root->p)<min_dis) min_dis=dis(tar,root->p);
  60. Node* left;
  61. if(tar.x[root->dim]<=root->p.x[root->dim]){
  62. search(root->lson,tar,min_dis);
  63. left=root->rson;
  64. }
  65. else{
  66. search(root->rson,tar,min_dis);
  67. left=root->lson;
  68. }
  69. if(pw(abs(tar.x[root->dim] - root->p.x[root->dim]))<=min_dis){
  70. search(left,tar,min_dis);
  71. }
  72. }

  1. //求曼哈顿距离最近和最远
  2. //维护四个最值
  3. struct Point{
  4. int x,y;
  5. Point(){}
  6. Point(int x,int y):x(x),y(y){}
  7. int dis(const Point& tmp)const{
  8. return abs(x-tmp.x)+abs(y-tmp.y);
  9. }
  10. };
  11. int DIM;
  12. bool cmp(const Point& a,const Point& b){
  13. return DIM?a.y<b.y:a.x<b.x;
  14. }
  15. struct Node{
  16. Point p;
  17. Node *lson,*rson;
  18. int mi[2],ma[2];
  19. Node(){
  20. lson = rson = NULL;
  21. }
  22. void setp(const Point& tp){
  23. this->p = tp;
  24. mi[0]=ma[0]=tp.x;
  25. mi[1]=ma[1]=tp.y;
  26. }
  27. void pushup(const Node& tp){
  28. mi[0]=min(mi[0],tp.mi[0]);
  29. ma[0]=max(ma[0],tp.ma[0]);
  30. mi[1]=min(mi[1],tp.mi[1]);
  31. ma[1]=max(ma[1],tp.ma[1]);
  32. }
  33. //求理论上可能的最小值
  34. int min_dis(const Point& tp){
  35. int ans=0;
  36. if(tp.x<mi[0] || tp.x>ma[0]){
  37. ans+= (tp.x<mi[0])?mi[0]-tp.x:tp.x-ma[0];
  38. }
  39. if(tp.y<mi[1] || tp.y>ma[1]){
  40. ans+= (tp.y<mi[1])?mi[1]-tp.y:tp.y-ma[1];
  41. }
  42. return ans;
  43. }
  44. //求理论上可能的最大值
  45. int max_dis(const Point& tp){
  46. return max(abs(tp.x-mi[0]),abs(tp.x-ma[0]))+max(abs(tp.y-mi[1]),abs(tp.y-ma[1]));
  47. }
  48. };
  49. //[l,r)
  50. void build(Node* &root,Point* p,int l,int r,int dep){
  51. if(l>=r){
  52. root=NULL;
  53. return ;
  54. }
  55. root = new Node;
  56. int sz=r-l;
  57. DIM = dep;
  58. nth_element(p+l,p+l+sz/2,p+r,cmp);
  59. root->setp(p[l+sz/2]);
  60. build(root->lson,p,l,l+sz/2,dep^1);
  61. build(root->rson,p,l+sz/2+1,r,dep^1);
  62. if(root->lson!=NULL) root->pushup(*(root->lson));
  63. if(root->rson!=NULL) root->pushup(*(root->rson));
  64. }
  65. void search_min(Node* &root,const Point& tar,int dep,int& ans){
  66. if(root==NULL) return ;
  67. if(root->p.dis(tar)!=0) ans=min(ans,root->p.dis(tar));
  68. if(root->lson==NULL && root->rson==NULL) return ;
  69. if(root->lson==NULL){
  70. search_min(root->rson,tar,dep+1,ans);
  71. }
  72. else if(root->rson==NULL){
  73. search_min(root->lson,tar,dep+1,ans);
  74. }
  75. else{
  76. if(root->lson->min_dis(tar) < root->rson->min_dis(tar)){
  77. if(root->lson->min_dis(tar)>=ans) return ;
  78. search_min(root->lson,tar,dep+1,ans);
  79. if(root->rson->min_dis(tar)<ans) search_min(root->rson,tar,dep+1,ans);
  80. }
  81. else{
  82. if(root->rson->min_dis(tar)>=ans) return ;
  83. search_min(root->rson,tar,dep+1,ans);
  84. if(root->lson->min_dis(tar)<ans) search_min(root->lson,tar,dep+1,ans);
  85. }
  86. }
  87. }
  88. void search_max(Node* &root,const Point& tar,int dep,int& ans){
  89. if(root==NULL) return ;
  90. ans=max(ans,root->p.dis(tar));
  91. if(root->lson==NULL && root->rson==NULL) return ;
  92. if(root->lson==NULL){
  93. search_max(root->rson,tar,dep+1,ans);
  94. }
  95. else if(root->rson==NULL){
  96. search_max(root->lson,tar,dep+1,ans);
  97. }
  98. else{
  99. if(root->lson->max_dis(tar) > root->rson->max_dis(tar)){
  100. if(root->lson->max_dis(tar)<=ans) return ;
  101. search_max(root->lson,tar,dep+1,ans);
  102. if(root->rson->max_dis(tar)>ans) search_max(root->rson,tar,dep+1,ans);
  103. }
  104. else{
  105. if(root->rson->max_dis(tar)<=ans) return ;
  106. search_max(root->rson,tar,dep+1,ans);
  107. if(root->lson->max_dis(tar)>ans) search_max(root->lson,tar,dep+1,ans);
  108. }
  109. }
  110. }

Min_25筛

可求素数之和
时间,空间大概

  1. struct HashTable{
  2. const static int N = 6.6e5+10;
  3. const static int mod = (1<<22)+1;
  4. int head[mod];
  5. int v[N],nex[N],cnt;
  6. ll u[N];
  7. HashTable(){
  8. memset(head,0,sizeof(head));
  9. cnt=1;
  10. }
  11. void insert(ll x,int id){
  12. int left=x%mod;
  13. v[cnt]=id,u[cnt]=x,nex[cnt]=head[left],head[left]=cnt++;
  14. }
  15. int query(ll x){
  16. int left=x%mod;
  17. for(int i=head[left];i;i=nex[i]){
  18. if(u[i]==x) return v[i];
  19. }
  20. return -1;
  21. }
  22. void clear(){
  23. memset(head,0,sizeof(head));
  24. cnt=1;
  25. }
  26. }ht;
  27. const int N=6.6e5+10;
  28. int pri[N],t;
  29. ll pris[N];
  30. bool vis[N];
  31. void init(){
  32. for(int i=2;i<N;i++){
  33. if(!vis[i]) pri[++t]=i;
  34. for(int j=1;j<=t;j++){
  35. int u=pri[j]*i;
  36. if(u>=N) break;
  37. vis[u]=1;
  38. if(i%pri[j]==0) break;
  39. }
  40. }
  41. for(int i=1;i<=t;i++) pris[i]=pris[i-1]+pri[i];
  42. }
  43. int Hash(int x){
  44. return upper_bound(pri+1,pri+t+1,x)-pri-1;
  45. }
  46. int sqr(ll x){
  47. int k=(int)sqrt(x+0.5);
  48. while(1LL*(k+1)*(k+1)<=x) k++;
  49. while(1LL*k*k>x) k--;
  50. return k;
  51. }
  52. int cou[N];
  53. ll v[N];
  54. double *dp[N];
  55. int len[N];
  56. double g(ll n,int j){
  57. if(j==0) return 1.0*n*(n+1)/2-1;
  58. int id=ht.query(n);
  59. if(j>len[id]) return g(n,len[id]);
  60. if(dp[id]==NULL){
  61. dp[id]=new double[len[id]+1];
  62. for(int i=0;i<len[id]+1;i++) dp[id][i]=-1.0;
  63. }
  64. if(dp[id][j]>=0) return dp[id][j];
  65. return dp[id][j]=g(n,j-1)-1.0*pri[j]*(g(n/pri[j],j-1)-pris[j-1]);
  66. }
  67. double cal(ll n){
  68. if(n<=1) return 0;
  69. ht.clear();
  70. int cnt=0;
  71. for(ll l=1,r;l<=n;l=r+1){
  72. r=n/(n/l);
  73. v[++cnt]=n/l;
  74. len[cnt]=Hash(sqr(n/l));
  75. ht.insert(n/l,cnt);
  76. }
  77. double ans=g(n,t);
  78. for(int i=1;i<=cnt;i++){
  79. if(dp[i]!=NULL) delete(dp[i]),dp[i]=NULL;
  80. }
  81. return ans;
  82. }

定义是积性函数

  1. struct HashTable{
  2. const static int N = 2.1e5+10;
  3. const static int mod = (1<<20)+1;
  4. int head[mod];
  5. int v[N],nex[N],cnt;
  6. ll u[N];
  7. HashTable(){
  8. memset(head,0,sizeof(head));
  9. cnt=1;
  10. }
  11. void insert(ll x,int id){
  12. int left=x%mod;
  13. v[cnt]=id,u[cnt]=x,nex[cnt]=head[left],head[left]=cnt++;
  14. }
  15. int query(ll x){
  16. int left=x%mod;
  17. for(int i=head[left];i;i=nex[i]){
  18. if(u[i]==x) return v[i];
  19. }
  20. return -1;
  21. }
  22. void clear(){
  23. memset(head,0,sizeof(head));
  24. cnt=1;
  25. }
  26. }ht;
  27. const int N=2.1e5+10;
  28. const int mod=1e9+7;
  29. struct PLL{
  30. int a;
  31. ll b;
  32. PLL(){
  33. a=b=-1;
  34. }
  35. PLL(ll a,ll b):a(a),b(b){}
  36. PLL operator - (const PLL& tmp)const{
  37. return PLL((0LL+a-tmp.a+mod)%mod,b-tmp.b);
  38. }
  39. PLL operator + (const PLL& tmp)const{
  40. return PLL((0LL+a+tmp.a)%mod,b+tmp.b);
  41. }
  42. PLL operator * (const PLL& tmp)const{
  43. return PLL((1LL*a*tmp.a)%mod,b*tmp.b);
  44. }
  45. }pris[N];
  46. int pri[N],t;
  47. bool vis[N];
  48. ll ps[N];
  49. void init(){
  50. for(int i=2;i<N;i++){
  51. if(!vis[i]) pri[++t]=i;
  52. for(int j=1;j<=t;j++){
  53. int u=pri[j]*i;
  54. if(u>=N) break;
  55. vis[u]=1;
  56. if(i%pri[j]==0) break;
  57. }
  58. }
  59. pris[0]=PLL(0,0);
  60. for(int i=1;i<=t;i++){
  61. pris[i]=pris[i-1]+PLL(pri[i],1);
  62. ps[i]=(ps[i-1]+(pri[i]^1))%mod;
  63. }
  64. }
  65. int Hash(int x){
  66. return upper_bound(pri+1,pri+t+1,x)-pri-1;
  67. }
  68. int sqr(ll x){
  69. int k=(int)sqrt(x+0.5);
  70. while(1LL*(k+1)*(k+1)<=x) k++;
  71. while(1LL*k*k>x) k--;
  72. return k;
  73. }
  74. int len[N];
  75. ll v[N];
  76. int *dpa[N];
  77. ll *dpb[N];
  78. PLL h(ll n,int j){
  79. if(j==0) return PLL((1LL*(n%mod)*(n%mod+1)/2-1)%mod,n-1);
  80. int id=ht.query(n);
  81. if(j>len[id]) return h(n,len[id]);
  82. if(dpa[id]==NULL){
  83. dpa[id] = new int[len[id]+1];
  84. dpb[id] = new ll[len[id]+1];
  85. for(int i=0;i<len[id]+1;i++) dpa[id][i]=-1,dpb[id][i]=-1;
  86. }
  87. if(dpa[id][j]>=0) return PLL(dpa[id][j],dpb[id][j]);
  88. PLL ans=h(n,j-1)-PLL(pri[j],1)*(h(n/pri[j],j-1)-pris[j-1]);
  89. dpa[id][j]=ans.a,dpb[id][j]=ans.b;
  90. return ans;
  91. }
  92. void initn(ll n){
  93. ht.clear();
  94. int cnt=0;
  95. for(ll l=1,r;l<=n;l=r+1){
  96. r=n/(n/l);
  97. v[++cnt]=n/l;
  98. len[cnt]=Hash(sqr(n/l));
  99. ht.insert(n/l,cnt);
  100. }
  101. }
  102. //[1,n] \sigma_{p is prime}f(p)
  103. ll cal(ll n){
  104. if(n<=1) return 0;
  105. PLL ans=h(n,t);
  106. return (0LL+ans.a+1-(ans.b-1))%mod;
  107. }
  108. int *G[N];
  109. ll g(ll n,int m){
  110. if(m>=1 && pri[m]>=n) return 0;
  111. if(m>=1 && n/pri[m]<=pri[m]){
  112. return (cal(n)-ps[m]+mod)%mod;
  113. }
  114. int id=ht.query(n);
  115. if(G[id]==NULL){
  116. G[id] = new int[len[id]+1];
  117. for(int i=0;i<len[id]+1;i++) G[id][i]=-1;
  118. }
  119. if(G[id][m]>=0) return G[id][m];
  120. ll ans=0;
  121. for(int i=m+1;1LL*pri[i]*pri[i]<=n;i++){
  122. ll cur=pri[i];
  123. for(int j=1;cur<=n;j++){
  124. ll tmp=g(n/cur,i)+((j>1)?1:0);
  125. (ans+=(pri[i]^j)*tmp)%=mod;
  126. cur*=pri[i];
  127. }
  128. }
  129. (ans+=cal(n)-ps[m])%=mod;
  130. return G[id][m]=ans;
  131. }
  132. void solve(ll n){
  133. initn(n);
  134. ll ans=g(n,0);
  135. cout<<(ans+1+mod)%mod<<endl;
  136. }

splay

平衡树,可以实现区间翻转

  1. struct Node{
  2. ll x,mi,tag;
  3. int sz;
  4. bool rev;
  5. Node *ch[2],*fa;
  6. Node(){}
  7. Node(ll x,Node* fa):x(x),fa(fa){
  8. ch[0] = ch[1] = NULL;
  9. mi = x,tag = 0,rev = 0,sz = 1;
  10. }
  11. void pushup(){
  12. mi = x,sz = 1;
  13. if(ch[0]!=NULL) mi = min(mi, ch[0]->mi),sz+=ch[0]->sz;
  14. if(ch[1]!=NULL) mi = min(mi, ch[1]->mi),sz+=ch[1]->sz;
  15. }
  16. };
  17. //如果u是它父亲的左儿子return 0,否则return 1
  18. int son(Node* u){
  19. return (u->fa->ch[1] == u);
  20. }
  21. //d=0 表示左旋
  22. void rotate(Node* root,int d){
  23. Node *f = root->fa;
  24. f->ch[d^1] = root->ch[d];
  25. if(root->ch[d]!=NULL) root->ch[d]->fa=f;
  26. root->fa = f->fa;
  27. if(f->fa!=NULL) f->fa->ch[son(f)]=root;
  28. f->fa = root;
  29. root->ch[d] = f;
  30. f->pushup(),root->pushup();
  31. }
  32. //把root旋转到s的儿子,rt是根节点
  33. void splay(Node *root,Node *s,Node* &rt){
  34. while(root->fa != s){
  35. Node *f = root->fa;
  36. /*
  37. rotate(root,son(root)^1);
  38. continue;
  39. */
  40. if(f->fa == s){
  41. rotate(root,son(root)^1);
  42. break;
  43. }
  44. else if(son(root) == son(root->fa)){
  45. int d = son(root);
  46. rotate(root->fa,d^1);
  47. rotate(root,d^1);
  48. }
  49. else{
  50. int d = son(root);
  51. rotate(root,d^1);
  52. rotate(root,d);
  53. }
  54. }
  55. if(s==NULL) rt = root;
  56. }
  57. void pushdown(Node* &root){
  58. if(root->rev){
  59. swap(root->ch[0],root->ch[1]);
  60. }
  61. if(root->ch[0]!=NULL){
  62. root->ch[0]->rev ^= root->rev;
  63. root->ch[0]->x += root->tag;
  64. root->ch[0]->mi += root->tag;
  65. root->ch[0]->tag += root->tag;
  66. }
  67. if(root->ch[1]!=NULL){
  68. root->ch[1]->rev ^= root->rev;
  69. root->ch[1]->x += root->tag;
  70. root->ch[1]->mi += root->tag;
  71. root->ch[1]->tag += root->tag;
  72. }
  73. root->rev = 0;
  74. root->tag = 0;
  75. }
  76. const int N=2e5+10;
  77. Node node[N];
  78. int cnt;
  79. Node* newNode(ll x,Node* f){
  80. node[cnt]=Node(x,f);
  81. return &node[cnt++];
  82. }
  83. ll a[N];
  84. void build(Node* &root,int l,int r,Node* f){
  85. if(l>r) return ;
  86. int m=(l+r)>>1;
  87. root = newNode(a[m],f);
  88. build(root->ch[0],l,m-1,root);
  89. build(root->ch[1],m+1,r,root);
  90. root->pushup();
  91. }
  92. //找到序列中第x个数并将它伸展到s的儿子
  93. void search(Node* &cur,int x,Node* s,Node* &rt){
  94. pushdown(cur);
  95. int lsz = (cur->ch[0]==NULL)?0:cur->ch[0]->sz;
  96. if(lsz >= x) search(cur->ch[0],x,s,rt);
  97. else if(x == lsz+1){
  98. splay(cur,s,rt);
  99. return ;
  100. }
  101. else search(cur->ch[1],x-1-lsz,s,rt);
  102. }
  103. //处理[l,r]区间,使第l-1个数在根节点,第r+1个数在根节点的右儿子
  104. void process(Node* &root,int l,int r){
  105. search(root,l,NULL,root);
  106. search(root,r+2,root,root);
  107. }
  108. //[l,r]区间加d
  109. void add(Node* &root,int l,int r,int d){
  110. process(root,l,r);
  111. Node* k = root->ch[1]->ch[0];
  112. k->x += d;
  113. k->mi += d;
  114. k->tag += d;
  115. }
  116. //翻转[l,r]区间
  117. void reverse(Node* &root,int l,int r){
  118. process(root,l,r);
  119. root->ch[1]->ch[0]->rev ^= 1;
  120. }
  121. //[l,r]区间左移cnt次
  122. void revolve(Node* &root,int l,int r,int cnt){
  123. cnt %= (r-l+1);
  124. if(!cnt) return ;
  125. reverse(root,l,r);
  126. reverse(root,l,l+cnt-1);
  127. reverse(root,l+cnt,r);
  128. }
  129. //第x个数后面添加一个数p
  130. void insert(Node* &root,int x,ll p){
  131. search(root,x+1,NULL,root);
  132. pushdown(root);
  133. if(root->ch[1]==NULL){
  134. root->ch[1] = newNode(p,root);
  135. root->pushup();
  136. return ;
  137. }
  138. Node* k = root->ch[1];
  139. while(1){
  140. pushdown(k);
  141. if(k->ch[0]==NULL) break;
  142. k=k->ch[0];
  143. }
  144. splay(k,root,root);
  145. k->ch[0] = newNode(p,k);
  146. k->pushup(),root->pushup();
  147. }
  148. //删掉第x个数
  149. void del(Node* &root,int x){
  150. search(root,x+1,NULL,root);
  151. pushdown(root);
  152. if(root->ch[1]==NULL){
  153. root = root->ch[0];
  154. root->fa = NULL;
  155. return ;
  156. }
  157. Node* k = root->ch[1];
  158. while(1){
  159. pushdown(k);
  160. if(k->ch[0]==NULL) break;
  161. k=k->ch[0];
  162. }
  163. splay(k,root,root);
  164. k->ch[0] = root->ch[0];
  165. if(k->ch[0]!=NULL) k->ch[0]->fa = k;
  166. root->ch[0] = NULL;
  167. root = k;
  168. if(root!=NULL) root->fa=NULL;
  169. }
  170. //[l,r]区间最小值
  171. ll min(Node* &root,int l,int r){
  172. process(root,l,r);
  173. pushdown(root);
  174. pushdown(root->ch[1]);
  175. pushdown(root->ch[1]->ch[0]);
  176. return root->ch[1]->ch[0]->mi;
  177. }
  178. //中序遍历splay
  179. void dfs(Node* root,vector<int>& ans){
  180. if(root==NULL) return ;
  181. pushdown(root);
  182. dfs(root->ch[0],ans);
  183. ans.push_back(root->x);
  184. dfs(root->ch[1],ans);
  185. }

treap

平衡树,比多一个求名次功能

  1. //通过赋予每个插入平衡树中的节点一个随机权值,在插入后根据权值进行旋转操作(类似堆的更新),树高O(logn)
  2. struct Node{
  3. int x,rk,sz;
  4. Node *ch[2];
  5. Node(int x):x(x){
  6. ch[0] = ch[1] = NULL;
  7. rk = rand();sz = 1;
  8. }
  9. int cmp(const int& y){
  10. if(x==y) return -1;
  11. return x<y?0:1;
  12. }
  13. void pushup(){
  14. sz=1;
  15. if(ch[0]!=NULL) sz+=ch[0]->sz;
  16. if(ch[1]!=NULL) sz+=ch[1]->sz;
  17. }
  18. };
  19. void rotate(Node* &root,int d){
  20. Node* k=root->ch[d^1];
  21. root->ch[d^1]=k->ch[d];
  22. k->ch[d]=root;
  23. root->pushup();k->pushup();
  24. root=k;
  25. }
  26. //在树上插入x,可重复
  27. void add(Node* &root,int x){
  28. if(root == NULL){
  29. root = new Node(x);
  30. return ;
  31. }
  32. int d=root->cmp(x);
  33. if(d==-1) d=0;
  34. add(root->ch[d^1],x);
  35. if(root->rk < root->ch[d^1]->rk) rotate(root,d);
  36. root->pushup();
  37. }
  38. //在树上删除x,重复的只删除一个
  39. void remove(Node* &root,int x){
  40. if(root==NULL) return ;
  41. int d=root->cmp(x);
  42. if(d==-1){
  43. Node* k = root;
  44. if(root->ch[0] == NULL){
  45. root = root->ch[1];
  46. delete(k);
  47. }
  48. else if(root->ch[1] == NULL){
  49. root = root->ch[0];
  50. delete(k);
  51. }
  52. else{
  53. int d = (root->ch[0]->rk < root->ch[1]->rk) ? 0 : 1;
  54. rotate(root,d);
  55. remove(root->ch[d],x);
  56. }
  57. }
  58. else remove(root->ch[d^1],x);
  59. if(root!=NULL) root->pushup();
  60. }
  61. //判断树上有没有x
  62. bool has(Node* &root,int x){
  63. if(root==NULL) return 0;
  64. int d = root->cmp(x);
  65. if(d==-1) return 1;
  66. return has(root->ch[d^1],x);
  67. }
  68. //集合第k大
  69. int kth(Node* &root,int k){
  70. if(k<=0) return 0;
  71. // not exist
  72. if(root == NULL) return 0;
  73. if(root->sz < k) return 0;
  74. int rsz = (root->ch[1]==NULL)?0:root->ch[1]->sz;
  75. if(rsz >= k) return kth(root->ch[1],k);
  76. else if(rsz+1 == k) return root->x;
  77. else return kth(root->ch[0],k-1-rsz);
  78. }
  79. void removetree(Node* &root){
  80. if(root==NULL) return ;
  81. removetree(root->ch[0]);
  82. removetree(root->ch[1]);
  83. delete(root);
  84. root=NULL;
  85. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注