【POJ2104】K-th Number

思路

  之前知道这道题是用<del>时代的眼泪</del>划分树写的TAT好复杂我看不懂

  然后主席就来拯救大家啦~\(≧▽≦)/~

  学了这么久还不会主席树QAQ今天才学的,又T又W的搞得我要死。。

  然后学到了离散化的新写法,不需要用Map。。

  基本思想就是针对[1,L]的每一个L开一个线段树,记录下[1,L]中每一个数出现的次数。

  然后L+1可以利用L的绝大部分点,不同的点重新开就好了。

  查询很好查,就跟Splay一样。

  

#include <iostream>

#include <cstring>

#include <string>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <queue>

#include <stack>

#include <map>

#include <set>

#include <list>

#include <vector>

#include <ctime>

#include <functional>

#define pritnf printf

#define scafn scanf

#define sacnf scanf

#define For(i,j,k) for(int i=(j);i<=(k);(i)++)

#define Clear(a) memset(a,0,sizeof(a))

using namespace std;

typedef unsigned int Uint;

const int INF=0x3fffffff;

const double eps=1e-10;

///==============struct declaration==============

struct Node{

   Node *lc,*rc;

   int sum;

   Node (){lc=rc=NULL;sum=0;}

};

///==============var declaration=================

const int MAXN=100010;

Node Poor[MAXN*30];int top=0;

//#define new(Node) (&Poor[++top])

int n,m,tot=0,k,v;

int A[MAXN],Sorted[MAXN];

int Id[MAXN];

map <int,int> Mp;

Node *Seg_Tree[MAXN],*null;

///==============function declaration============

void Add_Seg(Node *&L,Node *&R,int l,int r);

void Query(Node *&prev,Node *&o,int Rank,int l,int r);

void update(Node *&o,int l,int r);

///==============main code=======================

int main()

{

#define FILE__

#ifdef FILE__

   freopen("input.txt","r",stdin);

   freopen("output.txt","w",stdout);

#endif 

   scanf("%d%d",&n,&m);

   for(int i=1;i<=n;i++){

      scanf("%d",A+i);

      Sorted[i]=A[i];

   }

   null=new(Node);

   null->sum=0,null->lc=null,null->rc=null;

   sort(Sorted+1,Sorted+1+n);

   tot=unique(Sorted,Sorted+1+n)-Sorted-1;

   Seg_Tree[0]=new(Node);

   for(int i=1;i<=n;i++){

      Seg_Tree[i]=new(Node);   

      k=A[i];v=1;

      Add_Seg(Seg_Tree[i-1],Seg_Tree[i],1,tot);

   }

   while (m--){

      int L,R,K;scanf("%d%d%d",&L,&R,&K);

      Query(Seg_Tree[L-1],Seg_Tree[R],K,1,tot);

   }

   return 0;

}

///================fuction code====================

void Add_Seg(Node *&prev,Node *&o,int l,int r){

   int m=(l+r)>>1;

   if (prev==NULL) prev=null;

   if (o==NULL) o=new(Node);

   if (l==r)

      o->sum=v+prev->sum;

   else{

      if (Sorted[m]>=k){

         o->rc=prev->rc;

         o->lc=new(Node);

         Add_Seg(prev->lc,o->lc,l,m);

      }  

      else{

         o->lc=prev->lc;

         o->rc=new(Node);

         Add_Seg(prev->rc,o->rc,m+1,r);

      }

      update(o,l,r);

   }

}

void update(Node *&o,int l,int r){

   o->sum=0;

   if (o->lc!=NULL)  o->sum+=o->lc->sum;

   if (o->rc!=NULL)  o->sum+=o->rc->sum;

}

void Query(Node *&L,Node *&R,int Rank,int l,int r){

   if (L==NULL) L=null;

   if (R==NULL) R=null;

   int Lsum=0,m=(l+r)>>1;

   if (l==r){

      printf("%d\n",Sorted[l]);

      return ;

   }

   if (R->lc!=NULL)  Lsum+=R->lc->sum;

   if (L->lc!=NULL)  Lsum-=L->lc->sum;

   if (Lsum>=Rank)

      Query(L->lc,R->lc,Rank,l,m);

   else

      Query(L->rc,R->rc,Rank-Lsum,m+1,r);

}
POJ2104

 

你可能感兴趣的:(number)