poj 2104 & hdu 2665 kth number [주석 트 리 입문 문제 + 설명]
손 대 신의 교과서 몇 개 와 인터넷 에 많은 설명 을 하고 나의 이 해 를 말 해 보 세 요.
1. 주석 트 리 의 ls, rs 는 선분 트 리 의 좌우 점 과 다 릅 니 다. 전 자 는 엄격 한 의미 의 좌우 점 이 아니 라 좌우 뿌리 의 번호 입 니 다!
2. cnct 에 저 장 된 것 은 이 숫자 가 나타 난 횟수 라 는 점 은 의심 할 여지 가 없다.
3. 특정한 값 이 수정 되 었 을 때 이 점 은 루트 노드 라 는 길 (갈 라 지지 않 은) 까지 복사 한 다음 에 연결 점 의 번호 에 대응 하 는 변 화 는 관련 되 지 않 는 것 은 변 하지 않 는 다.인터넷 에서 수 동 쓰레기 를 회수 하면 메모리 비용 이 줄어든다 고 말 하 는 이유 다.
게다가 이 입문 문 제 는 구간 내 k 가 작 아야 한다.
먼저 배열 을 분 산 했 습 니 다.그리고 rt 배열 의 역할: 특정한 노드, 특정한 버 전 번 호 를 저장 하 는 대응 관계
/***********
poj2104
2016.1.24
24472K 1594MS C++ 1995B
***********/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100001;
struct Node
{
int ls,rs,cnt;
}tr[maxn*20];
int cur,rt[maxn];
void init()
{
cur=0;
}
inline void push_up(int o)
{
tr[o].cnt=tr[tr[o].ls].cnt+tr[tr[o].rs].cnt;
}
int build(int l,int r)
{
int k=cur++;
if(l==r)
{
tr[k].cnt=0;
return k;
}
int mid=(l+r)>>1;
tr[k].ls=build(l,mid);
tr[k].rs=build(mid+1,r);
push_up(k);
return k;
}
int update(int o,int l,int r,int pos,int val)
{
int k=cur++;
tr[k]=tr[o];
if(l==pos&&r==pos)
{
tr[k].cnt+=val;
return k;
}
int mid=(l+r)>>1;
if(pos<=mid) tr[k].ls=update(tr[o].ls,l,mid,pos,val);
else tr[k].rs=update(tr[o].rs,mid+1,r,pos,val);
push_up(k);
return k;
}
int query(int l,int r,int o,int v,int kth)
{
if(l==r) return l;
int mid=(l+r)>>1;
int res=tr[tr[v].ls].cnt-tr[tr[o].ls].cnt;
if(kth<=res) return query(l,mid,tr[o].ls,tr[v].ls,kth);
else return query(mid+1,r,tr[o].rs,tr[v].rs,kth-res);
}
int b[maxn],sortb[maxn];
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
//freopen("cin.txt","r",stdin);
int n,m,T;
//scanf("%d",&T);
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
sortb[i]=b[i];
}
sort(sortb+1,sortb+1+n);
int cnt=1;
for(int i=2;i<=n;i++)
if(sortb[i]!=sortb[cnt]) sortb[++cnt]=sortb[i];
rt[0]=build(1,cnt);
for(int i=1;i<=n;i++)
{
int p=lower_bound(sortb+1,sortb+1+cnt,b[i])-sortb;
rt[i]=update(rt[i-1],1,cnt,p,1);
}
for(int i=0;i<m;i++)
{
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
int idx=query(1,cnt,rt[a-1],rt[b],k);
printf("%d
",sortb[idx]);
}
}
return 0;
}
/***********
hdu2665
2016.1.24
826MS 25872K 2106 B G++
***********/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100001;
struct Node
{
int ls,rs,cnt;
}tr[maxn*20];
int cur,rt[maxn];
void init()
{
cur=0;
}
inline void push_up(int o)
{
tr[o].cnt=tr[tr[o].ls].cnt+tr[tr[o].rs].cnt;
}
int build(int l,int r)
{
int k=cur++;
if(l==r)
{
tr[k].cnt=0;
return k;
}
int mid=(l+r)>>1;
tr[k].ls=build(l,mid);
tr[k].rs=build(mid+1,r);
push_up(k);
return k;
}
int update(int o,int l,int r,int pos,int val)
{
int k=cur++;
tr[k]=tr[o];
if(l==pos&&r==pos)
{
tr[k].cnt+=val;
return k;
}
int mid=(l+r)>>1;
if(pos<=mid) tr[k].ls=update(tr[o].ls,l,mid,pos,val);
else tr[k].rs=update(tr[o].rs,mid+1,r,pos,val);
push_up(k);
return k;
}
int query(int l,int r,int o,int v,int kth)
{
if(l==r) return l;
int mid=(l+r)>>1;
int res=tr[tr[v].ls].cnt-tr[tr[o].ls].cnt;
if(kth<=res) return query(l,mid,tr[o].ls,tr[v].ls,kth);
else return query(mid+1,r,tr[o].rs,tr[v].rs,kth-res);
}
int b[maxn],sortb[maxn];
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
//freopen("cin.txt","r",stdin);
int n,m,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
sortb[i]=b[i];
}
sort(sortb+1,sortb+1+n);
int cnt=1;
for(int i=2;i<=n;i++)
if(sortb[i]!=sortb[cnt]) sortb[++cnt]=sortb[i];
rt[0]=build(1,cnt);
for(int i=1;i<=n;i++)
{
int p=lower_bound(sortb+1,sortb+1+cnt,b[i])-sortb;
rt[i]=update(rt[i-1],1,cnt,p,1);
}
for(int i=0;i<m;i++)
{
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
int idx=query(1,cnt,rt[a-1],rt[b],k);
printf("%d
",sortb[idx]);
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.