1 条题解
-
1lhs LV 8 @ 2023-8-3 9:56:18
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <map> #include <cstring> #include <iomanip> const int N = 1e6 + 10; const int INF = 0x3f3f3f3f; using namespace std; //last[i]表示上一次i出现的位置 //cnt[i]表示以ai结尾时完美序列的起始位置 int n , m, last[2*N], cnt[200010] , a[200010] , dp[200010][30] , l , r; void init() { for(int j = 1; (1 << j) <= n; j++) { for(int i = 1; i + (1 << j) - 1 <= n; i++) dp[i][j] = max(dp[i][j - 1] , dp[i + (1 << j - 1)][j - 1]); } } int find(int l , int r) { int k = log2(r - l + 1); return max(dp[l][k] , dp[r - (1 << k) + 1][k]); } int finda(int l , int r ) { int key = l; int ans = l - 1; while( l <= r) { int mid = l + r >> 1; if(cnt[mid] < key) { ans = mid; l = mid + 1; } else r = mid - 1; } return ans; } int main() { cin >> n >> m; for(int i = 1; i <= n; i++) scanf("%d" , &a[i]); //上一次a[1]出现的位置 last[a[1] + N] = 1; //以a1结尾时,完美序列的起始位置 cnt[1] = 1; //初始化dp dp[1][0] = 1; for(int i = 2; i <= n; i++) { //以a[i]结尾时的起点 cnt[i] = max(cnt[i - 1] , last[a[i] + N] + 1); dp[i][0] = i - cnt[i] + 1;//当前的最大长度 last[a[i] + N] = i;//更新当前数上一次出现的位置 } init(); while( m-- ) { scanf("%d%d" , &l , &r); l++ , r++;//确定查找范围 int ans = finda(l , r);//找到的位置 int ans1 = ans - l + 1; //如果在区间内 if(ans < r) ans1 = max(ans1 , find(ans + 1, r)); printf("%d\n" , ans1); } return 0; }
借鉴一下张老师的代码
- 1
信息
- ID
- 451
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 80
- 已通过
- 9
- 上传者