程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 2104&&2761 不修改的K大數 (主席樹)

POJ 2104&&2761 不修改的K大數 (主席樹)

編輯:C++入門知識

題目:查詢區間的K小數,不修改 繼續跟著島娘,適妞學習主席樹~~~~ 離散化。 以每個位置為起點,建立一棵主席樹,保存後綴區間的情況。 由於每個位置的主席樹其實是構造是完全相同的 在查詢的時候,便可以直接相減,T[l]-T[r+1]便是[l,r]區間的情況。 依舊是從後往前更新,建立主席樹。。 在前一個位置的基礎上,新建一棵樹,在當前位置更新 [cpp]  int n,q,m,tot;   int a[N],t[N];   int T[M],lson[M],rson[M],c[M];   void Init_hash(){       for(int i=1;i<=n;i++)           t[i]=a[i];       sort(t+1,t+1+n);       m=unique(t+1,t+1+n)-t-1;   }   int bulid(int l,int r){       int root=tot++;       c[root]=0;       if(l!=r){           int mid=(l+r)>>1;           lson[root]=bulid(l,mid);           rson[root]=bulid(mid+1,r);       }       return root;   }   int hash(int x){       return lower_bound(t+1,t+1+m,x)-t;   }   int update(int root,int pos,int val){       int newroot=tot++,tmp=newroot;       c[newroot]=c[root]+val;       int l=1,r=m;       while(l<r){           int mid=(l+r)>>1;           //cout<<l<<" "<<r<<endl;            if(pos<=mid){               lson[newroot]=tot++;rson[newroot]=rson[root];               newroot=lson[newroot];root=lson[root];               r=mid;           }           else{               rson[newroot]=tot++;lson[newroot]=lson[root];               newroot=rson[newroot];root=rson[root];               l=mid+1;           }           c[newroot]=c[root]+val;       }       return tmp;   }   int query(int left_root,int right_root,int k){       int l=1,r=m;       while(l<r){           int mid=(l+r)>>1;           if(c[lson[left_root]]-c[lson[right_root]]>=k){               r=mid;               left_root=lson[left_root];               right_root=lson[right_root];           }           else{               l=mid+1;               k-=c[lson[left_root]]-c[lson[right_root]];               left_root=rson[left_root];               right_root=rson[right_root];           }       }       return l;   }   int main(){       while(scanf("%d%d",&n,&q)!=EOF){           tot=0;           for(int i=1;i<=n;i++)               scanf("%d",&a[i]);           Init_hash();           T[n+1]=bulid(1,m);           for(int i=n;i;i--){               int pos=hash(a[i]);               T[i]=update(T[i+1],pos,1);           }           while(q--){               int l,r,k;               scanf("%d%d%d",&l,&r,&k);               printf("%d\n",t[query(T[l],T[r+1],k)]);           }       }       return 0;   }     int n,q,m,tot; int a[N],t[N]; int T[M],lson[M],rson[M],c[M]; void Init_hash(){     for(int i=1;i<=n;i++)         t[i]=a[i];     sort(t+1,t+1+n);     m=unique(t+1,t+1+n)-t-1; } int bulid(int l,int r){     int root=tot++;     c[root]=0;     if(l!=r){         int mid=(l+r)>>1;         lson[root]=bulid(l,mid);         rson[root]=bulid(mid+1,r);     }     return root; } int hash(int x){     return lower_bound(t+1,t+1+m,x)-t; } int update(int root,int pos,int val){     int newroot=tot++,tmp=newroot;     c[newroot]=c[root]+val;     int l=1,r=m;     while(l<r){         int mid=(l+r)>>1;         //cout<<l<<" "<<r<<endl;         if(pos<=mid){             lson[newroot]=tot++;rson[newroot]=rson[root];             newroot=lson[newroot];root=lson[root];             r=mid;         }         else{             rson[newroot]=tot++;lson[newroot]=lson[root];             newroot=rson[newroot];root=rson[root];             l=mid+1;         }         c[newroot]=c[root]+val;     }     return tmp; } int query(int left_root,int right_root,int k){     int l=1,r=m;     while(l<r){         int mid=(l+r)>>1;         if(c[lson[left_root]]-c[lson[right_root]]>=k){             r=mid;             left_root=lson[left_root];             right_root=lson[right_root];         }         else{             l=mid+1;             k-=c[lson[left_root]]-c[lson[right_root]];             left_root=rson[left_root];             right_root=rson[right_root];         }     }     return l; } int main(){     while(scanf("%d%d",&n,&q)!=EOF){         tot=0;         for(int i=1;i<=n;i++)             scanf("%d",&a[i]);         Init_hash();         T[n+1]=bulid(1,m);         for(int i=n;i;i--){             int pos=hash(a[i]);             T[i]=update(T[i+1],pos,1);         } www.2cto.com         while(q--){             int l,r,k;             scanf("%d%d%d",&l,&r,&k);             printf("%d\n",t[query(T[l],T[r+1],k)]);         }     }     return 0; }  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved