RMQ和线段树都能过,而且时间都500MS左右。
这道题主要还是思路的问题,特殊处理l,r所在的区间,中间的区间就用线段树区间求最值解决,想上去了代码很好实现。
RMQ代码:
#include<set> #include<map> #include<string> #include<vector> #include<stack> #include<queue> #include<cmath> #include<algorithm> #include<cstdio> #include<cstring> #include<iostream> using namespace std; #define _PI acos(-1.0) typedef long long LL; typedef pair<int,int> pill; /*==========================*/ #define MAXD 111111 int NumberR[MAXD],NumberL[MAXD]; int arr[MAXD]; int d[MAXD][20]; int n , m; void RMQinit(){ for(int i = 1 ; i <= n ; i++) d[i][0] = NumberL[i] + NumberR[i] - 1; for(int j = 1 ; (1 << j) <= n ; j++) for(int i = 1 ; i + (1 << j) - 1 <= n ; i ++) d[i][j] = max(d[i][j - 1],d[i + (1 << (j - 1))][j - 1]); } int solve(int l,int r){ int x = min(NumberR[l],r - l + 1); int y = min(NumberL[r],r - l + 1); l += x; r -= y; if(r < l) return max(x,y); int k = 0; while((1 << (k + 1)) <= r - l + 1) k ++; return max(max(x,y),max(d[l][k],d[r - (1 << k) + 1][k])); } int main(){ while(scanf("%d",&n) && n){ scanf("%d",&m); for(int i = 1 ; i <= n ; i++){ scanf("%d",&arr[i]); NumberL[i] = 1; NumberR[i] = 1; } for(int i = 2 ; i <= n ; i++) if(arr[i] == arr[i - 1]) NumberL[i] += NumberL[i - 1]; for(int i = n - 1 ; i >= 1 ; i --) if(arr[i] == arr[i + 1]) NumberR[i] += NumberR[i + 1]; RMQinit(); int x,y; for(int i = 0 ; i < m ; i++){ scanf("%d%d",&x,&y); int ans = solve(x,y); printf("%d\n",ans); } } return 0; }
线段树代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<map> using namespace std; typedef long long LL; const int maxn = 111111; int tr[maxn << 2]; int NumberL[maxn],NumberR[maxn]; int arr[maxn]; int n,cur; void BuildTree(int L,int R,int pos){ if(L == R){ tr[pos] = NumberL[cur] + NumberR[cur] - 1; cur ++; return ; } int m = (L + R) >> 1; BuildTree(L,m,pos << 1); BuildTree(m + 1,R ,pos << 1|1); tr[pos] = max(tr[pos << 1],tr[pos << 1|1]); return ; } int Query(int l,int r,int L,int R,int pos){ //求 l , r的最大值 if(l <= L && R <= r) return tr[pos]; int m = (L + R) >> 1; int ans = 0; if(l <= m) ans = max(ans,Query(l,r,L,m,pos << 1)); if(r > m) ans = max(ans,Query(l,r,m + 1,R,pos << 1|1)); return ans; } int solve(int l,int r){ int x = min(NumberR[l], r - l + 1); int y = min(NumberL[r], r - l + 1); l += x; r -= y; if(r < l) return max(x,y); int k = Query(l,r,1,n,1); //printf("%d %d %d\n",l,r,k); return max(max(x,y),max(x,k)); } int main(){ while(scanf("%d",&n) && n){ int m; scanf("%d",&m); for(int i = 1; i <= n ; i++){ scanf("%d",&arr[i]); NumberL[i] = 1; NumberR[i] = 1; } for(int i = 2 ; i <= n ; i ++) if(arr[i] == arr[i - 1]) NumberL[i] += NumberL[i - 1]; for(int i = n - 1 ; i >= 1 ; i--) if(arr[i] == arr[i + 1]) NumberR[i] += NumberR[i + 1]; cur = 1; BuildTree(1,n,1); for(int i = 0 ; i < m ; i ++){ int x , y; scanf("%d%d",&x,&y); int ans = solve(x,y); printf("%d\n",ans); } } return 0; }
时间: 2024-12-21 09:00:26