题目背景

$Maxtir$喜欢序列的中间值。


题目传送门(内部题127)


输入格式

  第一行输入两个正整数$n,m$,其中$m$是操作和询问次数。
  接下来两行每行输入$n$个非负整数,每一行分别表示两个序列$a,b$的初始值。
  接下来$m$行,每行输入一个操作或询问,以“$1\ x\ y\ z$或$2\ l_1\ r_1\ l_2\ r_2$”的形式给出。
  对于$1$操作,保证$x\in [0,1]$,若$x=0$,将$a_y$修改成$z$,否则将$b_y$修改成$z$,保证修改前后序列$a,b$都是非严格单调递增的。
  对于$2$操作,输出$a$序列的$[l_1,r_1]$区间与的$b$序列的$[l_2,r_2]$区间合并后形成的新区间的中间值,数据保证两个区间长度之和为奇数。


输出格式

  对于每个询问,输出一行一个整数$ans$表示答案。


样例

样例输入:

5 5
12 41 46 68 69  
35 61 82 84 96  
2 1 4 3 5
1 0 5 75
2 2 4 3 4
2 3 4 1 5
2 1 4 2 4

样例输出:

68
68
68
61


数据范围与提示

  对于$30\%$的数据,满足$n\leqslant 3,000,m\leqslant 2,000$
  对于$70\%$的数据,满足$n\leqslant 10^5,m\leqslant 2\times 10^5$
  对于$100\%$的数据,满足$n\leqslant 5\times 10^5,m\leqslant 10^6$
  $0\leqslant a_i,b_i,z\leqslant 10^9,1\leqslant l_1\leqslant r_1\leqslant n,1\leqslant l_2\leqslant r2\leqslant n$
  由于本题输入数据量较大,使用 scanf 读入数据也需要花费较多时间,建议采用下面的代码来读入一个非负整数。

int ri() {
char c = getchar(); int x = 0; for(;c < '0' || c > '9'; c = getchar());
for(;c >= '0' && c <= '9'; c = getchar()) x = x * 10 - '0' + c; return x;
}

题解

考虑如何利用单调不降的性质。

可以二分答案。

考虑如何$judge$,现在$a$上二分,再在$b$上二分(设当前二分的位置的左侧都位于中位数的左侧,反之同理),时间复杂度$\Theta(n\log^2 n)$;那么恭喜你被卡常了。

考虑怎么优化,如果我们在$a$上二分出来一个位置,那么由于已经知道了总长度,所以还能知道对应的$b$上的位置,于是就剪掉了一个$\log$。

需要注意的是边界问题,有很多处理方法,耐心调就好了。

温馨提醒:此题卡常,建议使用$AE86$

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,m;
int fh[2][500001];
namespace ae86{
const int bufl=1<<15;
char buf[bufl],*s=buf,*t=buf;
inline int fetch(){
if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
return*s++;
}
inline int read(){
int a=0,b=1,c=fetch();
while(!isdigit(c))b^=c=='-',c=fetch();
while(isdigit(c))a=a*10+c-48,c=fetch();
return b?a:-a;
}
}
using ae86::read;
void work1(){fh[read()][read()]=read();}
void work2()
{
int l1=read(),r1=read(),l2=read(),r2=read();
int len=(r1-l1+r2-l2+2)>>1;
int lft=l1,rht=r1;
while(lft<=rht)
{
int mid=(lft+rht)>>1;
int res=len-(mid-l1+1)+l2;
if(res==l2-1&&mid-l1&&fh[0][mid]<=fh[1][l2]){printf("%d\n",fh[0][mid]);return;}
if(res<l2){rht=mid-1;continue;}
else if(res>r2){lft=mid+1;continue;}
if(fh[0][mid]>=fh[1][res]&&(fh[0][mid]<=fh[1][res+1]||res==r2)){printf("%d\n",fh[0][mid]);return;}
if(fh[0][mid]>=fh[1][res])rht=mid-1;else lft=mid+1;
}
lft=l2,rht=r2;
while(lft<=rht)
{
int mid=(lft+rht)>>1;
int res=len-(mid-l2+1)+l1;
if(res==l1-1&&mid-l2&&fh[1][mid]<=fh[0][l1]){printf("%d\n",fh[1][mid]);return;}
if(res<l1){rht=mid-1;continue;}
else if(res>r1){lft=mid+1;continue;}
if(fh[1][mid]>=fh[0][res]&&(fh[1][mid]<=fh[0][res+1]||res==r1)){printf("%d\n",fh[1][mid]);return;}
if(fh[1][mid]>=fh[0][res])rht=mid-1;else lft=mid+1;
}
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)fh[0][i]=read();
for(int i=1;i<=n;i++)fh[1][i]=read();
for(int i=1;i<=m;i++)(read()==1)?work1():work2();
return 0;
}

rp++

[CSP-S模拟测试]:中间值(二分)的更多相关文章

  1. [CSP-S模拟测试]:序列(二分答案+树状数组)

    题目传送门(内部题98) 输入格式 第一行一个整数$n$,第二行$n$个整数$a_1\sim a_n$,第三行$n$个整数$b_1\sim b_n$. 输出格式 一行一个整数表示$\max(r-l+1 ...

  2. [CSP-S模拟测试]:maze(二分答案+最短路)

    题目传送门(内部题88) 输入格式 第一行两个数$n,m$.第二行四个数$sx,sy,tx,ty$.分别表示起点所在行数.列数,终点所在行数.列数.接下来$n$行,每行$m$个数,描述迷宫.最后一行一 ...

  3. [CSP-S模拟测试]:Merchant(二分答案)

    题目描述 有$n$个物品,第$i$个物品有两个属性$k_i,b_i$,表示它在时刻$x$的价值为$k_i\times x+b_i$.当前处于时刻$0$,你可以选择不超过$m$个物品,使得存在某个整数时 ...

  4. [CSP-S模拟测试]:Dinner(二分)

    题目描述 清儿今天请好朋友们吃饭,一共$N$个人坐在坐在圆桌旁.吃饭的第一步当然是点餐了.服务员拿来了$M$份菜单.第$i$个人阅读菜单并点出自己喜欢的菜需要花费时间$T_i$.当一个人点完菜之后,就 ...

  5. [CSP-S模拟测试]:平均数(二分答案+归并排序)

    题目描述 有一天,小$A$得到了一个长度为$n$的序列.他把这个序列的所有连续子序列都列了出来,并对每一个子序列都求了其平均值,然后他把这些平均值写在纸上,并对它们进行排序,最后他报出了第$k$小的平 ...

  6. [CSP-S模拟测试]:kill(二分答案+贪心)

    题目传送门(内部题50) 输入格式 第一行包含四个整数$n,m,s$,表示人数.怪物数及任务交付点的位置.第二行包含$n$个整数$p_1,p_2,...,p_n$.第三行包含$n$个整数$q_1,q_ ...

  7. .net单元测试——常用测试方式(异常模拟、返回值测试、参数测试、数据库访问代码测试)

    最近在看.net单元测试艺术,我也喜欢单元测试,今天介绍一下如何测试异常.如何测试返回值.如何测试模拟对象的参数传递.如何测试数据库访问代码.单元测试框架使用的是NUnit,模拟框架使用的是:Rhin ...

  8. csp-s模拟测试91

    csp-s模拟测试91 倒悬吃屎的一套题. $T1$认真(?)分析题意发现复杂度不能带$n$(?),计划直接维护答案,考虑操作对答案的影响,未果.突然发现可以动态开点权值线段树打部分分,后来$Tm$一 ...

  9. NOIP模拟测试19「count·dinner·chess」

    反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...

随机推荐

  1. python_0基础开始_day10

    第十节 一.函数进阶 动态参数 *a r g s —— 聚合位置参数,动态位置参数 默认返回的是tuple元组 def eat(*args):  # 函数的定义阶段 *聚合(打包)    print( ...

  2. java 如何编写多线程的代码

    线程是干活的所以线程一定是Thread,或者改线程实现Runnable接口多线程是竞争关系,所以多个线程竞争同一个资源,也就是同一个对象所以这个竞争对象发到Thread中即: // resources ...

  3. 怎么快速写好看的手机menu菜单

    要达到这样的效果: <div class="menu"> <div class="menu-1"> <img alt=" ...

  4. 【笔记】vue实现简单项目和页面跳转

    此项目适合不会前端,不会vue的人. 不会vue真正的开发,这里用vue和vant-ui简单搭一个商城app的tabbar和页面跳转. 装vue-cli3.0 根据官网快速上手搭建vant项目,官网 ...

  5. Keepalived+Nginx+Tomcat 实现高可用Web集群

    https://www.jianshu.com/p/bc34f9101c5e Keepalived+Nginx+Tomcat 实现高可用Web集群 0.3912018.01.08 20:28:59字数 ...

  6. Git复习(三)之分支管理、分支策略

    创建合并删除分支 我们知道每次提交git都会将他们串成一条线,这条时间线就是一个分支.在git里这条时间线叫做主分支,即master分支 HEAD指向master,master指向最新的提交,所以,H ...

  7. 关于redis的几件小事(二)redis线程模型

    1.memcached和redis有什么区别? (1)Redis支持服务器端的数据操作 redis和memcached相比,redis拥有更多的 数据结构并且支持更丰富的数据操作 ,通常在memcac ...

  8. 使用CSS设置背景图片,图片比较大,完全显示在一个DIV中

    做的时候想要边框为比较好看的样式,需要UI切图并且放在div中,看起来会好看点 像这样的,我随便挑选了一个,UI帮我切图出来 需要把这个图片填到相应的div里面,但是很显然碰到一个问题,图片太大,而且 ...

  9. selenium 模拟登陆豆瓣,爬取武林外传的短评

    selenium 模拟登陆豆瓣,爬去武林外传的短评: 在最开始写爬虫的时候,抓取豆瓣评论,我们从F12里面是可以直接发现接口的,但是最近豆瓣更新,数据是JS异步加载的,所以没有找到合适的方法爬去,于是 ...

  10. python爬去虎扑数据信息,完成可视化

    首先分析虎扑页面数据 如图我们所有需要的数据都在其中![image.png](1)所以我们获取需要的内容直接利用beaitifulsoupui4``` soup.find_all('a',class_ ...