데이터 구조의 - 선분 트 리 (1)
5535 단어 데이터 구조
선분 트 리 의 기본 적 인 응용 시 특정한 단락 의 합, 최대 최소 값 을 조회 하고 세그먼트 업데이트 로 매번 작업 의 복잡 도 를 log (n) 로 확보 합 니 다.
선분 수 에 관 한 글 이 많 으 니 참고 하 시기 바 랍 니 다 http://www.notonlysuccess.com/?p=59.
여기 서 저 는 hdu 와 poj 위의 선분 트 리 에 관 한 간단 한 응용 을 예 로 들 어 설명 합 니 다.
hdu 1166 (단일 업데이트, 구간 구 화):
적군 해안선 에는 n 개의 캠프 가 배열 되 어 있 으 며, 각 캠프 에는 몇 명의 병사 가 있 으 며, 각 캠프 의 병사 들 은 수시로 변동 (증가 또는 감소) 하고 있 으 며, 수시로 두 캠프 사이 의 병사 수의 합 을 구 해 야 한다.
우선 구조 선분 나무의 구조:
struct Seg_Tree
{
int left;//
int right;//
int value; //
int calmid()
{
return (left+right)>>1;
}
}tt[MAX*4];//MAX , 4
그 다음 에 선분 트 리 만 들 기:
int build(int left,int right,int idx)//idx 1
{
tt[idx].left = left;
tt[idx].right = right;
if(left == right)
return tt[idx].value = num[left];
int mid = (left + right)>>1;
return tt[idx].value = build(left,mid,LL(idx)) + build(mid+1,right,RR(idx));
}
어떤 캠프 에 병사 가 증가 하거나 감소 하 는 경우 업데이트 작업 이 있 습 니 다:
void update(int id,int x,int idx)
{
tt[idx].value += x;
if(tt[idx].left == tt[idx].right)
return;
int mid = tt[idx].calmid();
if(id <= mid)
update(id,x,LL(idx));
else
update(id,x,RR(idx));
}
어떤 캠프 의 병사 수 총 계 를 조회 하 세 요:
int query(int left,int right,int idx)
{
if(left == tt[idx].left && right == tt[idx].right)
return tt[idx].value;
int mid = tt[idx].calmid();
if(right <= mid)
return query(left,right,LL(idx));
else if(mid < left)
return query(left,right,RR(idx));
else
return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
}
hdu 1754 (단일 업데이트, 구간 최대 값):
선생님 은 학생 a 에서 학생 b 까지 의 가장 좋 은 성적 이 얼마 인지 물 어 보 는 것 을 좋아 합 니 다. 그 사이 에 일부 학생 들 의 성적 도 바 꿀 수 있 습 니 다.
선분 트 리 만 들 기:
int bulid(int left, int right, int idx)
{
tt[idx].left = left;
tt[idx].right = right;
if(left == right)
return tt[idx].value = num[left];
int mid = tt[idx].calmid();
return tt[idx].value = max(bulid(left,mid,LL(idx)), bulid(mid+1,right,RR(idx)));
}
어떤 학생 의 성적 변경 에 대해 업데이트 작업 이 있 습 니 다.
void update(int id, int value, int idx) // , : ,
{
if(tt[idx].left == tt[idx].right)
{
tt[idx].value = value;
return;
}
int mid = tt[idx].calmid();
if(id <= mid)
update(id,value,LL(idx));
else
update(id,value,RR(idx));
tt[idx].value = max(tt[LL(idx)].value, tt[RR(idx)].value);
}
어떤 단계 의 학생 성적 중 최대 치 를 조회 합 니 다.
int query(int left, int right, int idx)
{
if(left == tt[idx].left && right == tt[idx].right)
return tt[idx].value;
int mid = tt[idx].calmid();
if(right <= mid)
return query(left,right,LL(idx));
else if(left > mid)
return query(left,right,RR(idx));
else
return max(query(left,mid,LL(idx)), query(mid+1,right,RR(idx)));
}
상기 두 가지 예 제 는 단일 업데이트 에 대해 세그먼트 업데이트 에 대해 hdu 1698 이 있 습 니 다.
dota 안에 갈고리 가 있 는데 n 단 으로 구성 되 어 있 습 니 다. 처음에는 모두 구리 이 고 단락 당 무 게 는 1 입 니 다.지금 그 중에서 a - b 이 부분 을 금 이나 은 으로 바 꾸 려 고 합 니 다. (무 게 는 각각 3, 2) 이 갈고리 의 총 무 게 를 조회 해 야 합 니 다.
선분 트 리 만 들 기:
void build(int left, int right, int idx)
{
tt[idx].left = left;
tt[idx].right = right;
tt[idx].value = 1;// 1,-1 ( )
if(left == right)
return;
int mid = (left + right)>>1;
build(left,mid,LL(idx));
build(mid+1,right,RR(idx));
}
a - b 세그먼트 의 갈고리 업데이트:
void update(int left, int right, int value, int idx) //
{
if(left <= tt[idx].left && right >= tt[idx].right)
{
tt[idx].value = value;
return;
}
if(tt[idx].value != -1)
{
tt[LL(idx)].value = tt[RR(idx)].value = tt[idx].value;
tt[idx].value = -1; //
}
int mid = tt[idx].calmid();
if(left <= mid)
update(left,right,value,LL(idx));
if(mid < right)
update(left,right,value,RR(idx));
}
어떤 갈고리 의 무 게 를 조회 합 니 다:
int query(int left, int right, int idx)
{
if(left == tt[idx].left && right == tt[idx].right)
{
if(tt[idx].value != -1)
return (right-left+1)*tt[idx].value;
else
{
int mid = tt[idx].calmid();
return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
}
}
int mid = tt[idx].calmid();
if(right <= mid)
return query(left,right,LL(idx));
else if(left > mid)
return query(left,right,RR(idx));
else
return query(left,mid,LL(idx)) + query(mid+1,right,RR(idx));
}
선분 트 리 를 배우 고 선분 트 리 의 구 조 를 익히 고 찾 고 업데이트 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.