Codeforces Round #361 (Div. 2) D. Friends and Subsequences RMQ+二分

题目链接

http://codeforces.com/problemset/problem/689/D

代码

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 using namespace std;
 5
 6 const int maxn = 200000 + 10;
 7 int n, a[maxn], b[maxn];
 8 int d_min[maxn][30];
 9 int d_max[maxn][30];
10
11 void RMQ_init() {
12     for (int i = 0; i<n; i++) d_max[i][0] = a[i], d_min[i][0] = b[i];
13     for (int j = 1; (1 << j) <= n; j++)
14         for (int i = 0; i + (1 << j) - 1 < n; i++) {
15             d_min[i][j] = min(d_min[i][j - 1], d_min[i + (1 << (j - 1))][j - 1]);
16             d_max[i][j] = max(d_max[i][j - 1], d_max[i + (1 << (j - 1))][j - 1]);
17         }
18 }
19
20 int RMQ_min(int L, int R) {
21     int k = 0;
22     while ((1 << (k + 1)) <= R - L + 1) k++;
23     return min(d_min[L][k], d_min[R - (1 << k) + 1][k]);
24 }
25
26 int RMQ_max(int L, int R) {
27     int k = 0;
28     while ((1 << (k + 1)) <= R - L + 1) k++;
29     return max(d_max[L][k], d_max[R - (1 << k) + 1][k]);
30 }
31
32 int main()
33 {
34     cin >> n;
35     for (int i = 0; i < n; i++) scanf("%d", &a[i]);
36     for (int i = 0; i < n; i++) scanf("%d", &b[i]);
37     RMQ_init();
38     long long ans = 0;
39     for (int i = 0; i < n; i++) {
40         if (a[i] > b[i]) continue;
41         int first_r = -1, last_r = -1;
42         int l = i, r = n - 1, mid;
43
44         while (l <= r) {
45             mid = (l + r) / 2;
46             if (RMQ_max(i, mid) == RMQ_min(i, mid)) first_r = mid;
47             if (RMQ_max(i, mid) >= RMQ_min(i, mid)) r = mid - 1;
48             else l = mid + 1;
49         }
50         if (first_r == -1) continue;
51
52         l = i; r = n - 1;
53         while (l <= r) {
54             mid = (l + r) / 2;
55             if (RMQ_max(i, mid) > RMQ_min(i, mid))
56                 r = mid - 1;
57             else l = mid + 1, last_r = mid;
58         }
59
60         ans += last_r - first_r + 1;
61     }
62     cout << ans << endl;
63     return 0;
64 }
时间: 2024-09-30 04:45:36

Codeforces Round #361 (Div. 2) D. Friends and Subsequences RMQ+二分的相关文章

Codeforces Round #361 (Div. 2) D.Friends and Subsequences (multiset + 尺取法)

D. Friends and Subsequences Mike and !Mike are old childhood rivals, they are opposite in everything they do, except programming. Today they have a problem they cannot solve on their own, but together (with you) — who knows? Every one of them has an

Codeforces Round #361 (Div. 2) D - Friends and Subsequences

题目大意:给你两个长度为n的数组a, b,问你有多少个问你有多少个区间满足 a中最大值等于b中最小值. 思路:我本来的想法是用单调栈求出每个点的管辖区间,然后问题就变成了巨麻烦的线段覆盖问题,就爆炸写了 一晚上假算法.正解就是枚举一个端点,然后二分找右端点的区间,因为满足一个很神奇的单调性,然后st表维护 一下区间最值就好了. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #def

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序 题意 有 a[ i ] 个数 要求选最多的数 使其和不超过 S ,且在此情况下,和最小选最多数情况下 和最小 且 每个数有加成 如果选了 k个数 那么加成后 就是 a[ i ] + k*i ; 题解 二分mid 表示选了个数 加成一下,将加成以后结果排序一下 , 若前 mid数 和大于 s 则此方案不可行 PS 要用 long long ..... 还有 co

Codeforces Round#361(div 2)

A题题目意思很简单,问一种拨号的方式(拨号手势)是不是能拨出唯一的号码(例如253就不是唯一的,因为586也是可以的) 记录电话上每个格子上下左右是否还有格子,一个拨号手势是唯一的当且仅当,所拨号码的所有格子在同一个方向不同时有格子相邻. 那么直接mark,判断一下即可: #include <cstdio> using namespace std; char s[10000]; int n,U,D,L,R; int main(){ scanf("%d %s",&n,

Codeforces Round #361 (Div. 2) C D

C 给出一个m 此时有 四个数 分别为x k*x k*k*x k*k*k*x k大于1 x大于等于1 要求求出来一个最小的值n 使其满足 这四个数中的最大值小于n 这四个数可能的组数为m 可以看出这四个数递增 所以最大值必定是第四个 所以我们二分n 需要注意的是longlong可以定义到1e18 初始应当是l小于等于可能的最小值(0) r大于等于可能的最大值(1e18) 如果初始范围就定义错误的话 二分不会出现正确答案 在这里由于控制l=mid+1或者r=mid-1 这一类的时候 容易丢失mid

Codeforces Round #361 (Div. 2) D

D - Friends and Subsequences Description Mike and !Mike are old childhood rivals, they are opposite in everything they do, except programming. Today they have a problem they cannot solve on their own, but together (with you) — who knows? Every one of

【CF】Codeforces Round #361 (Div. 2)

难得有想法写一整套题解 首先想说的是,这场CF,我感觉是div2极为不错的一场(对于中档选手<因为我就出了三题,还掉了一个-- 说笑了,感觉这一场很耐人寻味.就是那种抓破头皮想不出,知道做法后细细品味,有种   哦~~~~~这样啊~~~~好神奇!!! 的感觉 首先..秀一下战绩 不多说了 都在题里 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ A. Mike and Cellphone time limit per test 1 second memory limit per test 256 megaby

Codeforces Round #361 (Div. 2) E. Mike and Geometry Problem

题目链接:传送门 题目大意:给你n个区间,求任意k个区间交所包含点的数目之和. 题目思路:将n个区间都离散化掉,然后对于一个覆盖的区间,如果覆盖数cnt>=k,则数目应该加上 区间长度*(cnt与k的组合数) ans=ans+(len*C(cnt,k))%mod; #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorith

Codeforces Round #422 (Div. 2) E. Liar 后缀数组+RMQ+DP

E. Liar The first semester ended. You know, after the end of the first semester the holidays begin. On holidays Noora decided to return to Vi?kopolis. As a modest souvenir for Leha, she brought a sausage of length m from Pavlopolis. Everyone knows th