codeforces基础题——#361(div2)D
来源:互联网 发布:ajax解析嵌套json数据 编辑:程序博客网 时间:2024/05/22 11:43
#361(Div 2) D
题目大意 :给你a, b两个长度为n的整数序列(1 <= n <= 200000), 问有多少个(l, r)(1 <= l, r <= n )使得a中区间(l, r)的最大值与b中区间(l, r)的最小值一样题解 : 一开始在想神奇的树状数组瞎搞做法, 其实可以做, 但写起来很麻烦, 于是写到一半太累(懒)了, 就没再写……此题正解十分简洁, 枚举左端点l,然后找右端点r的可行位置, 我们发现如果从i 到 i + j可行, 而i + j + 1不可行, 那么在之后应定不会有可行的右端点, 因为a中区间最大值只会增加, 而b中区间的最小值只会减少, 所以右端点r的可行位置一定在一段连续的区间中。那么怎找到这段区间呢, 注意左端点确定时,最大值与最小值具有单调性, 所以如果我们利用RMQ欲处理出最大值和最小值, 就能二分把区间找到,具体如下: 如果a中(l, mid)大于b中(l, mid)的值, 那么(mid + 1, r)的值一定是不合法的, 所以查找区间(l, mid), 合法的值一定在(mid + 1, r)中, 查找(mid +1, r); 通过比较大于和大于等于找出区间的左端点和右端点, 更新答案(然而我这里之前没想通, wa了几百次) 所以RMQ预处理, 暴力枚举l, 二分r可行区间即可, 时间复杂度O(nlogn)
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int a[200100], b[200100], n;int st1[200100][21], st2[200100][21], p[21], lg[200100];int rmq1(int i, int j){ int k = lg[j - i + 1]; return max(st1[i][k], st1[j - p[k] + 1][k]);}int rmq2(int i, int j){ int k = lg[j - i + 1]; return min(st2[i][k], st2[j - p[k] + 1][k]);}int main(){ scanf("%d", &n); for (int i = 1; i <= n; i ++)scanf("%d", &a[i]); for (int i = 1; i <= n; i ++)scanf("%d", &b[i]); int tmp = 2;p[0] = 1; for (int i = 1; i <= 20; i ++) p[i] = p[i - 1] * 2; for (int i = 2; i <= n; i ++) { lg[i] = lg[i - 1]; if (tmp <= i) lg[i] ++, tmp *= 2; //printf("%d %d\n", i, lg[i]); } for (int i = 1; i <= n; i ++) st1[i][0] = a[i], st2[i][0] = b[i]; for (int i = 1; i <= 20 && p[i] <= n; i ++) for (int j = 1; j <= n && j + p[i] - 1 <= n; j ++){ st1[j][i] = max(st1[j][i - 1], st1[j + p[i - 1]][i - 1]); st2[j][i] = min(st2[j][i - 1], st2[j + p[i - 1]][i - 1]); } long long ans = 0; for (int i = 1; i <= n; i ++){ if (a[i] > b[i]) continue; int l = i, r = n; while(l != r){ int mid = (l + r) >> 1; if (rmq1(i, mid) >= rmq2(i, mid)) r = mid; else l = mid + 1; } if (rmq1(i, r) != rmq2(i, l)) continue; int p = l; l = i, r = n + 1; while(l != r){ int mid = (l + r) >> 1; if (rmq1(i, mid) > rmq2(i, mid)) r = mid; else l = mid + 1;//printf("%d %d\n", l, r); } ans += l - p;// } printf("%I64d\n", ans); return 0;}
0 0
- codeforces基础题——#361(div2)D
- codeforces基础题——#362(div2)D
- codeforces基础题——#358(div2)D
- codeforces基础题——#357(div2) D
- codeforces基础题——#356(div2) D
- codeforces基础题——#362(div2)C
- codeforces基础题——#358(div2)C
- codeforces 136 div2 D题
- CodeForces #156 Div2 D题
- codeforces基础题——#356(div2) C
- codeforces基础题——#161(div2) E
- codeforces 93 div2 D题 - kmp- 3
- codeforces#256DIV2 D题Multiplication Table
- Codeforces Round #402 (Div2)D题
- codeforces 400(div2) D
- codeforces#ff(div2 D)
- Codeforces 292 div2 D
- codeforces #310 div2 D
- Linux 基本指令
- jsp前后台传值那点小事
- TabLayout
- 使用VerticalBannerView实现垂直轮播广告(仿淘宝头条)
- SQL语句操作SQLite数据库Demo
- codeforces基础题——#361(div2)D
- JavaEE实战——jsp入门、El表达式、JSTL标签库
- 在一个千万级的数据库查寻中,如何提高查询效率
- buildroot学习(十)——at91sam9g45软件平台更新
- 百度地图API(一)
- 深入学习absolute
- 第二周项目2 程序的多文件组织
- 【ITOO】AJAX提交Form表单
- 136 Single Number