zoukankan      html  css  js  c++  java
  • 「CF689D Friends and Subsequences」

    题目大意

    给出两个长度为 (n) 的序列 (a)(b),计算有多少对 (l,r) 满足 (max{a_l,a_{l+1},dots,a_{r-1},a_r}=min{b_l,b_{l+1},dots,b_{r-1},b_r}).

    分析

    考虑 (max)((min))的一些性质,(max{a_l,a_{l+1},dots,a_{r-1},a_r}leqmax{a_l,a_{l+1},dots,a_r,a_{r+1}})((min{b_l,b_{l+1},dots,b_{r-1},b_r}geqmin{b_l,b_{l+1},dots,b_r,b_{r+1}})),那么就可以发现这个东西是单调的,所以就很容易想到去二分查找.枚举左端点,查找右端点,可以发现符合条件的右端点肯定是一段区间(可能没有),那么可以二分出这个合法区间的左端点和右端点,然后就可以直接计算贡献了,考虑到取药计算区间最值,所以可以用st表维护.

    代码

    #include<bits/stdc++.h>
    #define REP(i,first,last) for(int i=first;i<=last;++i)
    #define DOW(i,first,last) for(int i=first;i>=last;--i)
    using namespace std;
    const int MAXN=3e5+7;
    int n;
    int a[MAXN];
    int log_2[MAXN];
    int lrmax[MAXN][24];
    int lrmin[MAXN][24];
    int QueryMax(int left,int right)//查询区间最大值
    {
    	int len=log_2[right-left+1];
    	return max(lrmax[left][len],lrmax[right-(1<<len)+1][len]);
    }
    int QueryMin(int left,int right)//查询区间最小值
    {
    	int len=log_2[right-left+1];
    	return min(lrmin[left][len],lrmin[right-(1<<len)+1][len]);
    }
    int main()
    {
    	scanf("%d",&n);
    	REP(i,1,n)
    	{
    		scanf("%d",&lrmax[i][0]);
    	}
    	REP(i,1,n)
    	{
    		scanf("%d",&lrmin[i][0]);
    	}
    	int now=0;
    	REP(i,1,n)//预处理log2(向下取整)
    	{
    		if(i==(1<<(now+1)))
    		{
    			++now;
    		}
    		log_2[i]=now;
    	}
    	REP(i,1,now)//预处理st表
    	{
    		REP(j,1,n+1-(1<<i))
    		{
    			lrmax[j][i]=max(lrmax[j][i-1],lrmax[j+(1<<(i-1))][i-1]);
    			lrmin[j][i]=min(lrmin[j][i-1],lrmin[j+(1<<(i-1))][i-1]);
    		}
    	}
    	int left,right,middle,l_appear,r_appear;
    	long long answer=0;//注意开long long
    	REP(i,1,n)
    	{
    		left=i;
    		right=n;
    		l_appear=0;
    		r_appear=0;
    		while(left<=right)//二分右端点
    		{
    			middle=(left+right)>>1;
    			if(QueryMax(i,middle)>QueryMin(i,middle))//如果max大了那么就减小
    			{
    				right=middle-1;
    			}
    			else
    			{
    				if(QueryMax(i,middle)==QueryMin(i,middle))//如果max和min相等则记录位置
    				{
    					r_appear=middle;
    				}
    				left=middle+1;
    			}
    		}
    		left=i;
    		right=n;
    		while(left<=right)//同理二分出左端点
    		{
    			middle=(left+right)>>1;
    			if(QueryMax(i,middle)>=QueryMin(i,middle))
    			{
    				if(QueryMax(i,middle)==QueryMin(i,middle))
    				{
    					l_appear=middle;
    				}
    				right=middle-1;
    			}
    			else
    			{
    				left=middle+1;
    			}
    		}
    		if(l_appear&&r_appear)//如果存在则计算贡献
    		{
    			answer+=(r_appear-l_appear+1);
    		}
    	}
    	printf("%lld",answer);
    	return 0;
    }
    
  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/Sxy_Limit/p/12671605.html
Copyright © 2011-2022 走看看