【UR #13】Yist
UOJ小清新题表
题目摘要
给出一个排列 \(A\) 以及它的一个非空子序列 \(B\),给出一个 \(x\) 并进行若干次操作,每一次操作需要在 \(A\) 中选择一个长度恰好为 \(x\) 的区间并删除它的最小值。如果在操作结束以后剩下的数组恰好是 \(B\),那么就可以得到 \(x\) 分,否则得到 \(0\) 分。
有 \(q\) 组询问,所有的 \(A\) 序列都是一样的,但 \(B\) 序列不同。求每次询问能得到的最大得分。
\(B\) 序列是一个 01 串,若该位置上为 \(1\) ,则表示 \(A\) 序列中该位置的数在 \(B\) 序列中出现了。
数据范围
\(2≤n≤1000000\),\(1≤q≤10\),\(A\) 为一个排列,\(B\) 为 \(A\) 的非空子序列,且 \(B≠A\)。
思路
可以先看看样例和解释。
我们可以枚举每一个可能要被删除的点。若其要被删除,向左扩展到第一个比他小的点 \(l\),向右扩展到地一个比他小的 \(r\),那么这两个点构成的开区间 \((l,r)\) 就是这个点要被删除时的极大区间。由于要保证必须满足条件,所以要在所有的极大区间中取最小,即为所要求的 \(x\)。
维护区间大小或者联通性之类的这种东西,很容易可以想到并查集。可以对下标开两个并查集,分别向左向右扩展。
比如要找到左边第一个比当前点小的点,需要把数从大到小加入,用并查集维护不用删除的点,也就是 \(B\) 序列中的每个 \(1\), 如果遇到 \(1\) ,则 \(fa[i]=i\) ,否则 \(fa[i]=\text{Find}(\ i-1\ )\) 。显然最后查询的时候需要跳过 \(1\) 。向右扩展同理。这样你每次都能找到极大区间,只需要取个 \(\min\) 即可。
一开始用前缀和维护一下 \(1\) 的个数,此点对应的极大区间就是扩展后的区间中 \(1\) 的个数加上自己(\(+1\))。
代码
建议改成:三目运算符带师
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int INF=0x3f3f3f3f;
int n,ans;
int a[maxn],pos[maxn],L[maxn],R[maxn],sum[maxn];
char s[maxn];
inline int read(){
int x=0,fopt=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')fopt=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-48;
return x*fopt;
}
int Find(int x,int fa[]){
return x==fa[x]?x:(fa[x]=Find(fa[x],fa));
}
inline void Solve(){
for(int i=1;i<=n;i++)
sum[i]=(s[i]=='1')?sum[i-1]+1:sum[i-1];
ans=INF;R[n+1]=n+1;
for(int i=1;i<=n;i++)
L[i]=(s[i]=='1')?i:Find(i-1,L);
for(int i=n;i>=1;i--)
R[i]=(s[i]=='1')?i:Find(i+1,R);
for(int i=n;i>=1;i--){
int v=pos[i];
if(s[v]=='1'){
L[v]=Find(v-1,L);
R[v]=Find(v+1,R);
}else ans=min(ans,sum[Find(v,R)-1]-sum[Find(v,L)]+1);//注意是开区间
}
}
int main(){
n=read();
for(int i=1;i<=n;i++){
a[i]=read();
pos[a[i]]=i;
}
int Q=read();
while(Q--){
scanf("%s",s+1);
Solve();
printf("%d\n",ans);
}
return 0;
}
【UR #13】Yist的更多相关文章
- uoj#186 【UR #13】Yist
题目 orz myy 首先注意到答案有单调性,于是我们可以考虑二分一个\(x\),之后去判断一下每次只使用长度为\(x\)的区间能否删出目标序列 显然我们应该贪心地删除需要删除元素中最小的那一个,感性 ...
- uoj#188. 【UR #13】Sanrd(Min_25筛)
题面 传送门 题解 这是一道语文题 不难看出,题目所求即为\(l\)到\(r\)中每个数的次大质因子 我们考虑\(Min\_25\)筛的过程,设 \[S(n,j)=\sum_{i=1}^nsec_p( ...
- uoj#187. 【UR #13】Ernd
http://uoj.ac/problem/187 每个点只能从时间,b+a,b-a三维都不大于它的点转移过来,将点按时间分成尽量少的一些段,每段内三维同时非严格单调,每段内的点可能因为连续选一段而产 ...
- UOJ 188 【UR #13】Sanrd——min_25筛
题目:http://uoj.ac/problem/188 令 \( s(n,j)=\sum\limits_{i=1}^{n}[min_i>=p_j]f(j) \) ,其中 \( min_i \) ...
- UOJ #188. 【UR #13】Sanrd
Description 给定 \(\sum_{i=l}^r f[i]\) \(f[i]=\) 把 \(i\) 的每一个质因子都从小到大排列成一个序列(\(p_i^{c_i}\)要出现 \(c_i\) ...
- UOJ188. 【UR #13】Sanrd
传送门 Sol 设 \(f_i\) 表示 \(i\) 的次大质因子 题目就是要求 \[\sum_{i=l}^{r}f_i\] 考虑求 \(\sum_{i=1}^{n}f_i\) 所求的东西和质因子有关 ...
- 「uoj#188. 【UR #13】Sanrd」
题目 不是很能看懂题意,其实就是求\([l,r]\)区间内所有数的次大质因子的和 这可真是看起来有点鬼畜啊 这显然不是一个积性函数啊,不要考虑什么特殊的函数了 我们考虑Min_25筛的过程 设\(S( ...
- UOJ188. 【UR #13】Sanrd [min_25筛]
传送门 思路 也可以算是一个板题了吧qwq 考虑min_25筛最后递归(也就是DP)的过程,要枚举当前最小的质因子是多少. 那么可以分类讨论,考虑现在这个质因子是否就是次大质因子. 如果不是,那么就是 ...
- 【UOJ#75】【UR #6】智商锁(矩阵树定理,随机)
[UOJ#75][UR #6]智商锁(矩阵树定理,随机) 题面 UOJ 题解 这种题我哪里做得来啊[惊恐],,, 题解做法:随机\(1000\)个点数为\(12\)的无向图,矩阵树定理算出它的生成树个 ...
随机推荐
- 购书网站前端实现(HTML+CSS+JavaScript)
购书+阅读静态网页设计与实现 一.主页设计HTML 1.效果展示及实现 2.完整代码 二.主页样式布局CSS 三.空间功能实现Javascript 主要功能 Javascript完整代码: 总结 购书 ...
- [Leetcode]Sql系列3
题目1 产品数据表: Products +---------------+---------+ | Column Name | Type | +---------------+---------+ | ...
- Python 开发GUI之UI界面的三种引入形式
[纯手工代码] # -*- coding: utf-8 -*- # Author:Jack LEE # FileName:main # CreatedDate: 2020/9/17 # 手写代码的基础 ...
- mariadb 1
mariadb(第一章) 数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们 ...
- openstack核心组件——neutron网络服务 抓取ip(9)
云计算openstack核心组件——neutron网络服务(9) 一.虚拟机获取 ip: 用 namspace 隔离 DHCP 服务 Neutron 通过 dnsmasq 提供 DHCP 服务 ...
- vue 中后台 列表的增删改查同一解决方案
查看 & 查询 常⻅业务列表⻚都是由 搜索栏 和 数据列表 组成. 其中: 搜索栏包含 搜索条件 . 新增 . 批量xx . 导出 等对 数据列表 全局操作功能项. 数据列表包含 分⻚ 和每条 ...
- RXJAVA之聚合操作
concat 按顺序连接多个Observables.需要注意的是Observable.concat(a,b)等价于a.concatWith(b). startWith 在数据序列的开头增加一项数据.s ...
- FTP服务端 FTP服务端搭建教程
FTP服务端搭建教程如下:一.需要准备以下工具:1.微型FTP服务端.2.服务器管理工具二.操作步骤:1.下载微型FTP服务端.(站长工具包可下载:http://zzgjb.iis7.com/ )2. ...
- c++中清空输入缓冲区的方法(做cf的时候炸了)
C/C++ 四种清空输入缓冲区的方法 比较实用的一种 char c; while(c=getchar()!='\n'); 或者是这种 cin.ignore(count,c); count代表要清除的字 ...
- 【Processing-日常3】等待动画1
之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/79755976