POJ 3368 Frequent values (RMQ)
제목
최대 100000 개의 수 를 포함 하 는 비 체감 수열 을 제시 하 는 데 최대 100000 번 이 있 습 니 다. 매번 L 번 째 숫자 에서 R 번 째 숫자 사이 의 가장 긴 숫자 가 같은 연속 서브 시퀀스 가 얼마나 되 는 지 물 어 봅 니 다.
문제 풀이 방법
ST 알고리즘 사용 가능
먼저 원 수열 의 연속 적 인 같은 부분 을 하나의 정수 로 압축 한다. 예 를 들 어 1, 1, 2, 2, 3, 3 을 3, 2, 4 로 압축 하고 압축 후 각 수 에 대응 하 는 원자 서열 의 시작 위 치 를 기록한다.
그리고 하나의 배열 dp [i] [j] 를 미리 처리 하 는 것 은 i 번 째 위치 부터 (1 < j) 개 수 를 나타 내 는 범위 내 최대 치 입 니 다.
그러면 질문 L - > R 에 대해 먼저 L 이라는 위 치 를 구하 고 앞으로 얼마나 똑 같은 지 를 구 한 다음 에 R 이라는 위치 에서 앞으로 몇 개의 똑 같은 기록 이 있 는 지 그들의 최대 치 는 중간 에 똑 같은 구간 에 대응 하 는 수 와 비교 하여 구체 적 으로 코드 를 봅 니 다.
참조 코드 - 궁금 한 점 이 있 으 시 면 아래 에 댓 글 을 남 겨 주시 면 바로 답 해 드 리 겠 습 니 다.
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
const int INF = 1<<29;
const double e = 2.71828;
int a[maxn], b[maxn], num[maxn], sta[maxn];
int dp[maxn][20];
int main() {
//freopen("in", "r", stdin);
int n, q;
while(scanf("%d%d", &n, &q) == 2) {
memset(dp, 0, sizeof(dp));
for( int i=0; i<n; i++ ) {
scanf("%d", &a[i]);
}
int pre = a[0], cut = 1;
int tn = 0; //tn
sta[0] = 0; //
for( int i=1; i<n; i++ ) {
if(a[i] == pre) cut++;
else {
b[tn] = a[i-1]; //b
num[tn++] = cut;
sta[tn] = i;
cut = 1;
pre = a[i];
}
}
b[tn] = a[n-1]; num[tn++] = cut;
for( int i=0; i<tn; i++ ) dp[i][0] = num[i]; // dp
for( int j=1; (1<<j)<tn; j++ ) {
for( int i=0; i<tn && i+(1<<j)-1<tn; i++ ) {
dp[i][j] = max(dp[i][j-1], dp[i+(1<<j)-1-(1<<(j-1))+1][j-1]);
}
}
for( int i=0; i<q; i++ ) {
int l, r;
scanf("%d%d", &l, &r);
l--, r--;
int L = lower_bound(b, b + tn, a[l]) - b;
int R = lower_bound(b, b + tn, a[r]) - b;
int ans = 0;
if(L == R) ans = max(ans, r-l+1);
else {
ans = max(ans, sta[L+1] - l); // L L R
ans = max(ans, r - sta[R] + 1); // R L R
if(L+1 != R) {
double tk = log(1.0*R-1-(L+1)+1)/log(2.0);
int tmp = tk;
ans = max(ans, max(dp[L+1][tmp], dp[R-1-(1<<tmp)+1][tmp]));
}
}
printf("%d
", ans);
}
}
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에 따라 라이센스가 부여됩니다.