【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\)的无向图,矩阵树定理算出它的生成树个 ...
随机推荐
- Repeater每行绑定事件代码
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { Repea ...
- C指针那点事儿
指针: 用来存放变量地址的变量,就成为"指针变量". 定义: 一般形式:类名标识符 *指针变量名; int *p; float *q; "*"是说明符,用来说明 ...
- 万字详解TDengine 2.0整体架构设计思路
导读:涛思数据8月3日将TDengine 的集群功能开源,TDengine具有超强的性能和功能,为什么能做到?它到底有哪些技术创新?今将TDengine的整体设计文档分享出来. 1: 数据模型 物联 ...
- HBase启用压缩
1. 压缩算法的比较 算法 压缩比 压缩 解压 GZIP 13.4% 21MB/s 118MB/s LZO 20.5% 135MB/s 410MB/s Snappy/Zippy 22.2% 172MB ...
- (专题四)05 matlab视角处理
方位角 视角 子图一 子图二,视点设置在图形的正上方 子图三,视点设置在图形侧面时的效果 子图四,十点设置在图形斜下方的效果 \circ用于输出符号° view函数的其他用法 视点在笛卡尔坐标中的位置 ...
- 4.Scala语法02 - 函数
- 3.Scala语法01 - 基础语法
- 深入理解HDFS分布式文件系统
深入理解HDFS:Hadoop分布式文件系统: https://blog.csdn.net/bingduanlbd/article/details/51914550
- golang开发:select多路选择
select 是 Golang 中的一个控制结构,语法上类似于switch 语句,只不过select是用于 goroutine 间通信的 ,每个 case 必须是一个通信操作,要么是发送要么是接收,s ...
- 干货满满!关于Pycharm远程开发
可以在Windows中使用Pycharm编写代码,而代码的调试运行可以使用远程服务器中的python解释器. 在本地创建好工程项目(或从git上clone下代码)后,用Pycharm打开: 打开「To ...