POJ 3776 Passing the Message

2583 단어 알고리즘ACM
제목: n 개의 수의 서열 을 제시 하고 각 수의 만 료 좌우 양쪽 에서 첫 번 째 로 큰 두 개의 구간 중 가장 큰 수 를 구하 십시오. 구간 이 0 이면 0 을 출력 합 니 다. 그렇지 않 으 면 출력 최대 치가 있 는 위치 입 니 다.서열 의 위 치 는 1 부터 계산한다.
사고: 먼저 예비 처 리 를 진행 합 니 다. lf [i] 는 모든 수의 왼쪽 이 그것 보다 큰 첫 번 째 수의 아래 표 시 를 1 로 추가 합 니 다. rn [i] 은 모든 수의 왼쪽 이 그것 보다 큰 첫 번 째 수의 아래 표 시 를 1 로 줄 입 니 다.하나의 수 i 의 왼쪽 구간 의 최대 값 인 lf [j] 는 lf [i] 와 같 기 때문에 찾 을 때 하나의 수의 lf [j] = lf [i] 만 찾 으 면 이 수 는 가장 큰 수 이 고 오른쪽 구간 은 같 습 니 다.
 
코드:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
const int maxn=50000+10;
int lf[maxn],rn[maxn],num[maxn];
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t,n,tcase=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        tcase++;
        for(int i=1;i<=n;++i)
          scanf("%d",&num[i]);
        num[n+1]=num[0]=inf;
        lf[0]=1;
        rn[n+1]=n;
        int p;
        for(int i=1;i<=n;++i)
        {
            p=i;
            lf[i]=i;
            while(num[i]>num[p-1])
            {
                lf[i]=lf[p-1];
                p=lf[p-1];
            }
        }
        for(int i=n;i>=1;--i)
        {
            p=i;
            rn[i]=i;
            while(num[i]>num[p+1])
            {
                rn[i]=rn[p+1];
                p=rn[p+1];
            }
        }
        int ul,ur,pl,pr;
        printf("Case %d:
",tcase); for(int i=1;i<=n;++i) { ul=i-1; ur=i+1; pl=pr=0; if(lf[i]!=i&&i-1!=0) { pl=ul; while(lf[ul]!=lf[i]) { if(ul==lf[ul]) ul--; else ul=lf[ul]-1; pl=ul; } } if(rn[i]!=i&&i!=n) { pr=ur; while(rn[ur]!=rn[i]) { if(ur==rn[ur]) ur++; else ur=rn[ur]+1; pr=ur; } } printf("%d %d
",pl,pr); } } return 0; }

좋은 웹페이지 즐겨찾기