• 可持久线段树


    思想和可持久化trie一模一样,在历史版本的基础上构建新版本,即只增加发生改变的那条路径。

    代码是用可持久化线段树实现的主席树,并通过了poj2104/hdu2665两个求区间第k大题

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<string.h>
      4 #include<map>
      5 #include<queue>
      6 #include<set>
      7 #include<iostream>
      8 #include<vector> 
      9 #define MAXN 1000005 
     10 using namespace std;
     11 typedef long long ll;
     12 
     13 int tot=1;  //注意0节点作为虚拟空节点
     14 struct Node{
     15     int sum,lson,rson;
     16     Node(){
     17         sum=lson=rson=0;
     18     }
     19     Node operator + (const Node &t)const
     20     {
     21         Node res;
     22         
     23         res.sum=sum+t.sum;
     24         
     25         return res;
     26     }
     27 }node[2000015];
     28 
     29 
     30 int ins(int k,int num,int x,int l,int r) //在k树x位置+num并构建新树 
     31 {    int tmp=tot++; 
     32     int mid=(l+r)/2;
     33     if(l==r)
     34     {
     35         node[tmp].lson=node[tmp].rson=0;
     36         node[tmp].sum=node[k].sum+num;
     37     }
     38     else if(x<=mid)
     39     {
     40         int t=ins(node[k].lson,num,x,l,mid);
     41         int t2=node[k].rson;
     42         node[tmp]=node[t]+node[t2];
     43         node[tmp].lson=t,node[tmp].rson=t2;
     44     }
     45     else
     46     {    
     47         int t2=ins(node[k].rson,num,x,mid+1,r);
     48         int t=node[k].lson;
     49         node[tmp]=node[t]+node[t2];
     50         node[tmp].lson=t,node[tmp].rson=t2;
     51     }
     52 
     53     return tmp;
     54 }
     55 int query(int lroot,int rroot,int l,int r,int k) //查询第k大 
     56 {    
     57     if(l==r) return l;
     58     int mid=(l+r)/2;
     59     int sum=node[node[rroot].lson].sum-node[node[lroot].lson].sum;
     60 
     61     if(sum>=k)
     62     {
     63         return query(node[lroot].lson,node[rroot].lson,l,mid,k);
     64     }
     65     else return query(node[lroot].rson,node[rroot].rson,mid+1,r,k-sum);
     66 }
     67 int a[100005],sorted[100005],root[100005];
     68 int main()
     69 {   int T;
     70     scanf("%d",&T);
     71     while(T--)
     72     {    
     73         tot=1;
     74         root[0]=0;
     75         int n,m;
     76         scanf("%d%d",&n,&m);
     77     
     78         for(int i=1;i<=n;i++)
     79         {
     80             scanf("%d",&a[i]);
     81             sorted[i]=a[i];
     82         }
     83          sort( sorted + 1, sorted + 1 + n );
     84         int num = unique( sorted + 1, sorted + n + 1 ) - ( sorted + 1 );
     85         for ( int i = 1; i <= n; ++i )
     86         {
     87             
     88             int pos = lower_bound( sorted + 1, sorted + num + 1, a[i] ) - sorted;
     89             
     90             root[i]=ins(root[i-1],1,pos,1,num);
     91       
     92          
     93         }
     94         int l,r,k;
     95         while(m--)
     96         {
     97             scanf("%d%d%d",&l,&r,&k);
     98        
     99             int pos = query(root[l-1],root[r],1,num,k);
    100             printf("%d
    ", sorted[pos]);
    101         }
    102     }
    103     
    104     
    105     return 0;
    106 }
  • 相关阅读:
    笔试的坑 onsubmit事件
    正则之
    笔试:找出一个字符串中字符出现最多的次数和该字符
    createDocumentFragment和insertAdjacentHTML
    css权威指南学习笔记--第七章
    使用gulp-minify-css的坑
    arguments[0]() 笔试题的坑
    快速搭建本地服务器
    voxel折腾指南
    力扣第72题 编辑距离
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/9252318.html
Copyright © 2020-2023  润新知