학습 노트 - 간단 한 배증 알고리즘 - st 알고리즘

단순 배가 알고리즘 에 대하 여
배가
st 알고리즘
배가 되 는 해석
배가 알고리즘 에 대해 말하자면 배로 증가 하여 생략 할 수 있 는 계산 을 뛰 어 넘 고 가속 효 과 를 얻 는 것 이다.
st 알고리즘
배가 되면 st 알고리즘 을 제시 하지 않 을 수 없다. 이것 은 아마도 배가 되 는 가장 전형 적 인 응용 일 것 이다.st 알고리즘 은 RMQ 문제 (구간 최대 값), 즉 하나의 서열 에서 수치 가 가장 큰 항목 을 구 하 는 데 적용 된다.소박 한 방법 은 자 연 스 럽 게 스 캔 을 통 해 최대 치 를 찾 는 것 이지 만 문제 의 질문 횟수 가 많 을 때 시간 을 초과 할 가능성 이 높 기 때문에 배증 알고리즘 으로 최적화 시킨다.
다음은 st 알고리즘 이 RMQ 문 제 를 해결 하 는 실현 입 니 다.
우선, 우 리 는 f [i] [j] 로 서열 a 에서 i 번 째 숫자 이후 2j 개 수의 최대 치 를 표시 하면 f [i] [0] = a [i] 를 얻 을 수 있다.
다음은 DP 과정 을 진행 합 니 다.
for(int j = 1;j <= ( log2(n) ); j++)
	for(int i = 1;i <= n - (1 << j) + 1; i++)
		f[i][j] = max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

f [i] [j] 가 표시 하 는 구간 은 [i, i + 2j] 의 최대 치 이 고 2j = 2 * 2j - 1 = 2j - 1 + 2j - 1 이 므 로 우 리 는 구간 [i, i + 2j] 을 [i, i + 2j - 1] 과 [i + 2j - 1 + 1, 2j] 로 나 눌 수 있다.구간 을 두 부분 으로 나 눌 수 있 으 니 DP 의 사고방식 이 명확 해 지고 f [i] [j] 의 값 을 구 할 수 있다.
그러나 문제 가 묻 는 구간 이 꼭 2 의 멱 차방 이 아니 라 구간 을 초과 할 수 있다.
따라서 l 을 구간 길이 로 설정 하고 조회 할 때 k = log 2 (l) 를 구하 여 아래로 조정 할 수 있 습 니 다.
그러면: l / 2 < = 2k < = l
max (f [i] [k], f [i + 2j - 2k] [k]) 가 원 하 는 구간 의 최대 치 입 니 다.
처음 블 로 그 를 쓰 는데 잘 못 쓰 는 것 도 양해 해 주세요. 저녁 에 도 좀 졸 리 니까 코드 를 달 아 주세요.
Luogu P3865
#include
#include
#include

using namespace std;

long f[100001][40];
int n,m;

int main(){
    cin>>n>>m;
    
    int temp;
    for(int i=1;i<=n;i++){
        scanf("%d",&temp);
        
        f[i][0]=temp;
    }
    for(int k=1;k<=(int)log2(n);k++){
        for(int i=1;i<=n-(1<<k)+1;i++){
            f[i][k]=max(f[i][k-1],f[i+(1<<(k-1))][k-1]);
        }
    }
    int l,r;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&l,&r);
        
        int k=log2(r-l+1);
        
        printf("%d
"
,max(f[l][k],f[r-(1<<k)+1][k])); } return 0; }

좋은 웹페이지 즐겨찾기