1272 最大距離(線段樹 / 排序思維)
阿新 • • 發佈:2018-11-11
1272 最大距離
- 1 秒
- 131,072 KB
- 20 分
- 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;
}