。。可持久化线段树模板题
具体讲解看CLJ神犇的论文,总之函数式编程的关键就是不要赋值,每次都新建节点就好了。
【代码】
/************************
ID:Ciocio
LANG:C++
DATE:2014-1-22
TASK:Feed the dogs
************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
#define MAXP 4000000
#define MAXN 100005
#define m_p make_pair
#define INF 999999999
struct Tree{
Tree* lc;
int sz;
Tree* rc;
};
Tree Pool[MAXP];
Tree* New=Pool;
Tree* null;
Tree* P[MAXN];
int N,M;
typedef pair<int,int> pii;
pii V[MAXN];
int initkey[MAXN],mat[MAXN];
void _read(int &x)
{
char tt=getchar();
while(tt<'0'||'9'<tt) tt=getchar();
for(x=0;'0'<=tt&&tt<='9';x=(x<<1)+(x<<3)+tt-'0',tt=getchar());
}
char t[100];
void _write(int x,int j=1)
{
if(x==0) putchar('0');
for(;x;x/=10,j++) t[j]=x%10+'0';
for(j--;j;j--) putchar(t[j]);
putchar('\n');
}
Tree* Get(Tree* lc,int sz,Tree* rc)
{
New->lc=lc;
New->sz=sz;
New->rc=rc;
return New++;
}
Tree* Insert(Tree* T,int loc,int Left,int Right)
{
if(Left==Right) return Get(0,T->sz+1,0);
int Mid=(Left+Right)>>1;
Tree* tmp;
if(loc<=Mid)
{
tmp=Insert(T->lc,loc,Left,Mid);
return Get(tmp,tmp->sz+T->rc->sz,T->rc);
}
if(loc>=Mid+1)
{
tmp=Insert(T->rc,loc,Mid+1,Right);
return Get(T->lc,T->lc->sz+tmp->sz,tmp);
}
}
void _renumbered()
{
sort(V+1,V+N+1);
int tmp=0;
V[0]=m_p(-INF,0);
for(int i=1;i<=N;i++)
{
if(V[i].first!=V[i-1].first) tmp++;
initkey[V[i].second]=tmp;
mat[tmp]=V[i].first;
}
}
void _init()
{
_read(N);_read(M);
int x;
null=Get(0,0,0);
null->lc=null;
null->rc=null;
P[0]=null;
for(int i=1;i<=N;i++)
{
_read(x);
V[i]=m_p(x,i);
}
_renumbered();
for(int i=1;i<=N;i++) P[i]=Insert(P[i-1],initkey[i],1,N);
}
int Search(Tree* A,Tree* B,int k,int Left,int Right)
{
int Mid=(Left+Right)>>1;
if(Left==Right) return Left;
if(k<=B->lc->sz-A->lc->sz)
return Search(A->lc,B->lc,k,Left,Mid);
else
{
k-=B->lc->sz-A->lc->sz;
return Search(A->rc,B->rc,k,Mid+1,Right);
}
}
void _solve()
{
int a,b,k;
for(int i=1;i<=M;i++)
{
_read(a);_read(b);_read(k);
_write(mat[Search(P[a-1],P[b],k,1,N)]);
}
}
int main()
{
_init();
_solve();
return 0;
}