• [CF689D] Friends and Subsequences(RMQ, 二分)


    题目链接:http://codeforces.com/contest/689/problem/D

    题意:给出两个数列a,b,问有多少个下标相同的区间,使该区间内a的最大值等于b的最小值。

    预处理出a,b每个区间内的最大值或最小值,之后枚举每一个位置,由于min[l,r]>=min[l,r+1],max[l,r]<=max[l,r+1],根据这个性质我们可以二分枚举两个序列中从i除法a的最大值等于b的最小值的右端点,用lower_bound和upper_bound可以确定这个右端点的范围,即右端点在这个范围内无论如何取结果都成立,所以这个区间的子区间个数为[r-l+1]。

      1 /*
      2 ━━━━━┒ギリギリ♂ eye!
      3 ┓┏┓┏┓┃キリキリ♂ mind!
      4 ┛┗┛┗┛┃\○/
      5 ┓┏┓┏┓┃ /
      6 ┛┗┛┗┛┃ノ)
      7 ┓┏┓┏┓┃
      8 ┛┗┛┗┛┃
      9 ┓┏┓┏┓┃
     10 ┛┗┛┗┛┃
     11 ┓┏┓┏┓┃
     12 ┛┗┛┗┛┃
     13 ┓┏┓┏┓┃
     14 ┃┃┃┃┃┃
     15 ┻┻┻┻┻┻
     16 */
     17 #include <algorithm>
     18 #include <iostream>
     19 #include <iomanip>
     20 #include <cstring>
     21 #include <climits>
     22 #include <complex>
     23 #include <fstream>
     24 #include <cassert>
     25 #include <cstdio>
     26 #include <bitset>
     27 #include <vector>
     28 #include <deque>
     29 #include <queue>
     30 #include <stack>
     31 #include <ctime>
     32 #include <set>
     33 #include <map>
     34 #include <cmath>
     35 using namespace std;
     36 #define fr first
     37 #define sc second
     38 #define cl clear
     39 #define BUG puts("here!!!")
     40 #define W(a) while(a--)
     41 #define pb(a) push_back(a)
     42 #define Rint(a) scanf("%d", &a)
     43 #define Rs(a) scanf("%s", a)
     44 #define Cin(a) cin >> a
     45 #define FRead() freopen("in", "r", stdin)
     46 #define FWrite() freopen("out", "w", stdout)
     47 #define Rep(i, len) for(int i = 0; i < (len); i++)
     48 #define For(i, a, len) for(int i = (a); i < (len); i++)
     49 #define Cls(a) memset((a), 0, sizeof(a))
     50 #define Clr(a, x) memset((a), (x), sizeof(a))
     51 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
     52 #define lrt rt << 1
     53 #define rrt rt << 1 | 1
     54 #define pi 3.14159265359
     55 #define RT return
     56 #define lowbit(x) x & (-x)
     57 #define onecnt(x) __builtin_popcount(x)
     58 typedef long long LL;
     59 typedef long double LD;
     60 typedef unsigned long long ULL;
     61 typedef pair<int, int> pii;
     62 typedef pair<string, int> psi;
     63 typedef pair<LL, LL> pll;
     64 typedef map<string, int> msi;
     65 typedef vector<int> vi;
     66 typedef vector<LL> vl;
     67 typedef vector<vl> vvl;
     68 typedef vector<bool> vb;
     69 
     70 const int maxn = 200200;
     71 int dp[maxn][20][2];
     72 
     73 void st(int* a, int* b, int n) {
     74     for(int i = 1; i <= n; i++) dp[i][0][0] = b[i], dp[i][0][1] = a[i];
     75     for(int j = 1; (1 << j) - 1 <= n; j++) {
     76         for(int i = 1; i + (1 << j) - 1 <= n; i++) {
     77             dp[i][j][0] = min(dp[i][j-1][0], dp[i+(1<<(j-1))][j-1][0]);
     78             dp[i][j][1] = max(dp[i][j-1][1], dp[i+(1<<(j-1))][j-1][1]);
     79         }
     80     }
     81 }
     82 
     83 int query(int l, int r) {
     84     int k = int(log(r-l+1) / log(2.0));
     85     return max(dp[l][k][1], dp[r-(1<<k)+1][k][1]) - min(dp[l][k][0], dp[r-(1<<k)+1][k][0]);
     86 }
     87 
     88 int n;
     89 int a[maxn], b[maxn];
     90 
     91 int lower(int x) {
     92     int lo = x, hi = n;
     93     int ret = n;
     94     while(lo <= hi) {
     95         int mid = (lo + hi) >> 1;
     96         int cur = query(x, mid);
     97         if(cur > 0) hi = mid - 1;
     98         else if(cur < 0) lo = mid + 1;
     99         else {
    100             ret = min(ret, mid);
    101             hi = mid - 1;
    102         }
    103     }
    104     return ret;
    105 }
    106 
    107 int upper(int x) {
    108     int lo = x, hi = n;
    109     int ret = -1;
    110     while(lo <= hi) {
    111         int mid = (lo + hi) >> 1;
    112         int cur = query(x, mid);
    113         if(cur > 0) hi = mid - 1;
    114         else if(cur < 0) lo = mid + 1;
    115         else {
    116             ret = max(ret, mid);
    117             lo = mid + 1;
    118         }
    119     }
    120     return ret;
    121 }
    122 
    123 int main() {
    124     // FRead();
    125     while(~Rint(n)) {
    126         For(i, 1, n+1) Rint(a[i]);
    127         For(i, 1, n+1) Rint(b[i]);
    128         st(a, b, n);
    129         LL ret = 0;
    130         For(i, 1, n+1) {
    131             int lo = lower(i);
    132             int hi = upper(i);
    133             if(lo <= hi) ret += hi - lo + 1;
    134         }
    135         cout << ret << endl;
    136     }
    137     RT 0;
    138 }
  • 相关阅读:
    浏览器的同源策略及跨域解决方案
    前端开发工具系列
    初始Vue
    form表单组件
    聚合和分组F,Q和事物,cookie,session
    js循环找id
    div模拟textarea文本域轻松实现高度自适应
    prototype原型
    Javascript异步编程方法
    js中map、filter用法
  • 原文地址:https://www.cnblogs.com/kirai/p/5809792.html
Copyright © 2020-2023  润新知