zoukankan      html  css  js  c++  java
  • codeforces 689D D. Friends and Subsequences(RMQ+二分)

    题目链接:

    D. Friends and Subsequences

    time limit per test
    2 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    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 integer sequences a and b of length n. Being given a query of the form of pair of integers (l, r), Mike can instantly tell the value of  while !Mike can instantly tell the value of .

    Now suppose a robot (you!) asks them all possible different queries of pairs of integers (l, r(1 ≤ l ≤ r ≤ n) (so he will make exactlyn(n + 1) / 2 queries) and counts how many times their answers coincide, thus for how many pairs  is satisfied.

    How many occasions will the robot count?

     
    Input
     

    The first line contains only integer n (1 ≤ n ≤ 200 000).

    The second line contains n integer numbers a1, a2, ..., an ( - 109 ≤ ai ≤ 109) — the sequence a.

    The third line contains n integer numbers b1, b2, ..., bn ( - 109 ≤ bi ≤ 109) — the sequence b.

     
    Output
     

    Print the only integer number — the number of occasions the robot will count, thus for how many pairs  is satisfied.

    Examples
     
    input
    6
    1 2 3 2 1 4
    6 7 1 2 3 2
    output
    2
    input
    3
    3 3 3
    1 1 1
    output
    0

    题意:

    在一个区间[l,r]中a的最大值等于b的最小值,问这样的区间有多少个;

    思路:

    枚举左端点,二分找到右端点可行区间的左右边界;
    在确定右段点的左右边界时,要用RMQ,
    左边界:要是amax>=bmin,左移;否则右移,找到第一个amax=bmin的点;
    右边界:要是amax>bmin,左移,否则右移,找到最后一个amax=bmin的点;

    累加右端点可行区间长度即可;

    AC代码:

    //#include <bits/stdc++.h>
    #include <vector>
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef  long long LL;
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=2e5+10;
    const int maxn=1005;
    const double eps=1e-10;
    
    int a[N],b[N],MX[N][21],MN[N][21],n;
    struct Tree
    {
        int l,r;
        int mmax,mmin;
    }tr[4*N];
    
    void build(int o,int L,int R)
    {
        for(int i=1;i<=n;i++)
        MX[i][0]=a[i],MN[i][0]=b[i];
        for(int j=1;(1<<j)<=n;j++)
        {
            for(int i=1;i+(1<<j)-1<=n;i++)
            {
                MX[i][j]=max(MX[i][j-1],MX[i+(1<<(j-1))][j-1]);
                MN[i][j]=min(MN[i][j-1],MN[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int query(int o,int L,int R,int flag)
    {
        if(flag)
        {
            int k = 0;
            while( (1<<(k+1)) <= R-L+1) k ++ ;
            return max(MX[L][k],MX[R-(1<<k)+1][k]);
        }
        else
        {
            int k = 0;
            while( (1<<(k+1)) <= R-L+1) k ++ ;
            return min(MN[L][k],MN[R-(1<<k)+1][k]);
        }
    }
    int check(int x,int y,int flag)
    {
        int mx=query(1,x,y,1),mn=query(1,x,y,0);
      if(flag){  if(mx==mn)return 1;
                else if(mx>mn)return 2;
                    return 0;}
        else
        {
            if(mx==mn)return 1;
            return 0;
        }
    }
    int main()
    {
        read(n);
        For(i,1,n)read(a[i]);
        For(i,1,n)read(b[i]);
        build(1,1,n);
        LL ans=0;
        int L,R;
        For(i,1,n)
        {
            int l=i,r=n;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(!check(i,mid,1))l=mid+1;
                else r=mid-1;
            }
            L=l;
            if(check(i,L,1)==2)continue;
            l=L,r=n;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(check(i,mid,0))l=mid+1;
                else r=mid-1;
            }
            R=l-1;
            if(R>=L)ans=ans+(R-L+1);
        }
        cout<<ans<<"
    ";
            return 0;
    }
  • 相关阅读:
    PYTHON核心编程第7章 7.5题
    openssl大漏洞
    运维之路
    组件嵌套+Mixin函数demo
    React初识(按钮点击+输入绑定)
    vue切换按钮(关闭消失型)
    动态发表之后的显示时间
    展开全部的实现
    前端进行后台数据的处理
    将项目上传到git上,并在测试服务器上运行
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5656012.html
Copyright © 2011-2022 走看看