AtCoder Beginner Contest 381-E

Problem

一个长度为奇数、最中间的那个字符是 /、左边所有字符都是都是 1、右边所有字符都是 2 的字符串被称为11/22 字符串

更加严谨的定义:

当一个字符串 \(T\) 满足以下所有条件时,它被称为11/22 字符串

  • \(|T|\) 是奇数。这里, \(|T|\) 表示 \(T\) 的长度。
  • 从第 \(1\) 到第\((\frac{|T|+1}{2} - 1)\) 个字符都是 1
  • 第 \((\frac{|T|+1}{2})\) 个字符是/
  • 从第 \((\frac{|T|+1}{2} + 1)\) 到第 \(|T|\) 的字符都是 2

例如,11/22111/222/是 11/22 字符串,但11221/22211/22222/11/2/2/211则不是。

给定由12/组成的字符串 \(S\) ,\(|S|=N\)。有 \(Q\) 次询问:给定 \(L\) 和 \(R\),设 \(T\) 是 \(S\) 的从第 \(L\) 个字符到第 \(R\) 个字符组成的子串。请找出 \(T\) 的最长子序列使得该子序列是一个 11/22 字符串。如果不存在这样的子序列,则打印 "0"。

Constraints

  • \(1 \leq N \leq 10^5\)
  • \(1 \leq Q \leq 10^5\)
  • \(S\) is a string of length \(N\) consisting of 1, 2, and /.
  • \(1 \leq L \leq R \leq N\)
  • \(N\), \(Q\), \(L\), and \(R\) are integers.

Solution

考虑预处理出所有/的位置,记作 \(pos_i\)。

使用前缀和后缀和计算“每一个字符之前有多少个1”和“每一个字符之后有多少个2”,分别记作 \(left1_i\) 和 \(right2_i\)。

对于每次询问,一个简单暴力的算法就是,枚举在该区间内的所有/,并看看其左右分别有多少个12,则选择该/作为11/22子串的中间的那个/能够找出的最长子序列长度为

\[\begin{align}
ans_i=\min\{left1_{pos_i}-left1_{L},right2_{pos_i}-right2_{R}\} \quad L\le pos_i \le R
\end{align}
\]

即可以利用预处理的信息,在\(O(1)\)的时间复杂度内计算出选择某个/时的答案。

并且可以通过二分 \(pos_i\) 来得到需要枚举的 \(i\) 的范围。

但是这样还是需要枚举 \([L,R]\) 内的所有/,如果/很多就寄了。

观察上式可以发现,随着 \(pos_i\) 增大,\(left1_{pos_i}-left1_L\) 单调递增,\(right2_{pos_i}-right2_R\) 单调递减。\(\min\{增函数,减函数\}\) 一定是一个开口向下的单峰函数,所以可以使用三分来确定最佳的 \(pos_i\)。

Code

#define N 1000010

int left1[N],left2[N],right1[N],right2[N];
int n,q;
string str;
int pos[N],cnt;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
// cin>>t;
while(t--)
{
cin>>n>>q;
cin>>str;
str=" "+str;
// pos[++cnt]=0;
for(int i=1;i<=n;i++)
{
if(str[i]=='/')
{
pos[++cnt]=i;
}
}
pos[++cnt]=n+1;
int pre1=0,pre2=0;
for(int i=1;i<=n;i++)
{
left1[i]=pre1;
left2[i]=pre2;
if(str[i]=='1') pre1++;
if(str[i]=='2') pre2++;
}
pre1=pre2=0;
for(int i=n;i>=1;i--)
{
right1[i]=pre1;
right2[i]=pre2;
if(str[i]=='1') pre1++;
if(str[i]=='2') pre2++;
} while(q--)
{
int a,b,ans=0;cin>>a>>b;
// 确定左右边界,即找到最远的一对杠但是在[a,b]之内
int l=lower_bound(pos+1,pos+cnt+1,a)-pos;
int r=upper_bound(pos+1,pos+cnt+1,b)-pos-1;
// DEBUG1(l);
// DEBUG1(r);
while(l+3000<r)
{
int mid1=l+(r-l)/3;
int mid2=r-(r-l)/3;
int p1=pos[mid1],p2=pos[mid2];
int s1=min(left1[p1]-left1[a],right2[p1]-right2[b]);
int s2=min(left1[p2]-left1[a],right2[p2]-right2[b]);
if(s1<s2)
{
l=mid1;
}
else{
r=mid2;
}
}
for(int i=l;i<=r;i++)
{
int p=pos[i];
if(str[p]=='/')
{
// cout<<"calc "<<i<<endl;
// cout<<min(left1[p]-left1[a],right2[p]-right2[b])<<endl;
ans=max(ans,1+2*min(left1[p]-left1[a],right2[p]-right2[b]));
}
}
cout<<ans<<endl;
} }
return 0;
}

AtCoder Beginner Contest 381-E的更多相关文章

  1. AtCoder Beginner Contest 100 2018/06/16

    A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...

  2. AtCoder Beginner Contest 052

    没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...

  3. AtCoder Beginner Contest 053 ABCD题

    A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...

  4. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

  5. AtCoder Beginner Contest 137 F

    AtCoder Beginner Contest 137 F 数论鬼题(虽然不算特别数论) 希望你在浏览这篇题解前已经知道了费马小定理 利用用费马小定理构造函数\(g(x)=(x-i)^{P-1}\) ...

  6. AtCoder Beginner Contest 076

    A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...

  7. AtCoder Beginner Contest 079 D - Wall【Warshall Floyd algorithm】

    AtCoder Beginner Contest 079 D - Wall Warshall Floyd 最短路....先枚举 k #include<iostream> #include& ...

  8. AtCoder Beginner Contest 064 D - Insertion

    AtCoder Beginner Contest 064 D - Insertion Problem Statement You are given a string S of length N co ...

  9. AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle【暴力】

    AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle 我要崩溃,当时还以为是需要什么离散化的,原来是暴力,特么五层循环....我自己写怎么都 ...

  10. AtCoder Beginner Contest 075 C bridge【图论求桥】

    AtCoder Beginner Contest 075 C bridge 桥就是指图中这样的边,删除它以后整个图不连通.本题就是求桥个数的裸题. dfn[u]指在dfs中搜索到u节点的次序值,low ...

随机推荐

  1. css3 渐变边框如何实现圆角效果

    常规的 border-image 属性如果直接使用 border-radius 会无效,关于如何实现渐变边框圆角,网上流传着大概这么几种办法: 渐变背景方式(仅适用于纯底色背景) 借助 after 伪 ...

  2. Laravel11 从0开发 Swoole-Reverb 扩展包(一) - 扩展包开发

    前言 大家好呀,我是yangyang.好久没更新了,最近新项目在使用laravel11(截止目前发文,laravel12也发布了)做开发,自己也是利用有些空闲时间做些除开业务以外的深入学习,因此也就萌 ...

  3. datagrid源码

    /** * jQuery EasyUI 1.2.3 * * Licensed under the GPL terms * To use it on other terms please contact ...

  4. Ubuntu Nvidia driver驱动安装(新)

    前言 英伟达更新了安装驱动的方式,更新一下文档 旧文:Ubuntu Nvidia driver驱动安装及卸载 下载官方驱动安装 1.安装驱动前一定要更新软件列表和安装必要软件.依赖(必须) sudo ...

  5. Vmware ESXi 是免费吗?一文弄懂vSphere功能特性及ESXi与vSphere到底有什么区别和联系。

    目录 收起 一.对VMware vSphere及ESXi的相关疑问 1.Vmware vSphere 有些什么功能? 2.ESXi 是否真正免费? 3. ESXi 和 vSphere 到底有什么区别, ...

  6. 设置git忽略文件

    要设置Git忽略文件,你可以使用一个名为.gitignore的特殊文件.在这个文件中,你可以列出需要Git忽略的文件.文件夹.或者匹配模式.当Git执行操作时,它会自动忽略这些被列出的文件. 1. 在 ...

  7. 【Python】PDF文档导出指定章节为TXT

    PDF文档导出指定章节为TXT 需求 要导出3000多个pdf文档的特定章节内容为txt格式(pdf文字可复制). 解决 导出PDF 查了一下Python操作PDF文档的方法,主要是通过3个库,PyP ...

  8. 关于CH182LED配置的说明

    CH182的LED配置有两种模式: 传统LED功能 该功能可通过页7寄存器19控制bit 3-5控制 使用时可将页7寄存器19 bit3 置0 通过bit4-5实现不同模式,默认情况下bit3为0,b ...

  9. HL7消息编辑器的使用手册

    REDISANT 提供互联网与物联网开发测试套件 # 互联网与中间件: Redis Assistant ZooKeeper Assistant Kafka Assistant RocketMQ Ass ...

  10. Sentinel源码—4.FlowSlot实现流控的原理

    大纲 1.FlowSlot根据流控规则对请求进行限流 2.FlowSlot实现流控规则的快速失败效果的原理 3.FlowSlot实现流控规则中排队等待效果的原理 4.FlowSlot实现流控规则中Wa ...