1. 程式人生 > >1272 最大距離(線段樹 / 排序思維)

1272 最大距離(線段樹 / 排序思維)

1272 最大距離

  1. 1 秒
  2.  
  3. 131,072 KB
  4.  
  5. 20 分
  6.  
  7. 3 級題

給出一個長度為N的整數陣列A,對於每一個數組元素,如果他後面存在大於等於該元素的數,則這兩個數可以組成一對。每個元素和自己也可以組成一對。例如:{5, 3, 6, 3, 4, 2},可以組成11對,如下(數字為下標):

(0,0), (0, 2), (1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (3, 3), (3, 4), (4, 4), (5, 5)。其中(1, 4)是距離最大的一對,距離為3。

 收起

輸入

第1行:1個數N,表示陣列的長度(2 <= N <= 50000)。
第2 - N + 1行:每行1個數,對應陣列元素Ai(1 <= Ai <= 10^9)。

輸出

輸出最大距離。

輸入樣例

6
5
3
6
3
4
2

輸出樣例

3

題解:思路一:用結構體封裝起 值和位置,按值排序(值相同時,按“位置”排序),遍歷一遍,當“位置”大於之前的“位置”,                                意味著距離可以更新。

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=max(tree[rt<<1],tree[rt<<1|1])
#define nth(k,n) nth_element(a,a+k,a+n);  // 將 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 約瑟夫
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const double pi = atan(1.)*4.;
const int M=1e3+5;
const int N=1e5+5;
struct fun{
    int a,id;
}f[N];
bool cmp(fun x,fun y){
    if(x.a==y.a)
        return x.id<y.id;
    else
        return x.a<y.a;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&f[i].a),f[i].id=i;
    sort(f,f+n,cmp);
    int tem=f[0].id,ans=0;  //  ans 存放最遠距離
    for(int i=1;i<n;i++){
        if(tem>f[i].id) tem=f[i].id;
        else ans=max(ans,f[i].id-tem);   // 更新
    }
    printf("%d\n",ans);
    return 0;
}

思路二:線段樹+二分割槽間,區間只需要統計最大值

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=max(tree[rt<<1],tree[rt<<1|1])
#define nth(k,n) nth_element(a,a+k,a+n);  // 將 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 約瑟夫
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const double pi = atan(1.)*4.;
const int M=1e3+5;
const int N=1e5+5;
int n;
int tree[N<<2],a[N];
void sett(int l,int r,int rt){
    if(l==r){
        tree[rt]=a[l];
        return ;
    }
    int mid=l+r>>1;
    sett(l,mid,rt<<1);
    sett(mid+1,r,rt<<1|1);
    pushup();
}

int findd(int a,int b,int l,int r,int rt){
    if(a<=l&&b>=r)
        return tree[rt];
    int ans=0;
    int mid=l+r>>1;
    if(a<=mid)
        ans=max(ans,findd(a,b,l,mid,rt<<1));
    if(b>mid)
        ans=max(ans,findd(a,b,mid+1,r,rt<<1|1));
    return ans;
}

bool J(int x,int mid){
    int d=findd(mid,n,1,n,1);
    if(d>=x) return true;
    else return false;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sett(1,n,1);
    int ans=0;
    for(int i=1;i<n;i++){
        int l=i,r=n;
        while(r-1>l){
            int mid=l+r>>1;
            if(J(a[i],mid)) l=mid;
            else r=mid;
        }
        if(J(a[i],r)) ans=max(ans,r-i);
        else ans=max(ans,l-i);
    }
    printf("%d\n",ans);
    return 0;
}