1 条题解
-
0
自动搬运
来自洛谷,原作者为

xiaoyaowudi
想回到最初原点 拨琴弦唱起岁月 不畏惧未来渺远 只牵挂那心愿搬运于
2025-08-24 22:37:35,当前版本为作者最后更新于2022-04-05 09:40:27,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
给定一个排列 和一个字符串 , 由大于小于号组成,求 中最长的子序列 使得 的大小关系和 相同。
。
分析
下文假设如果 表示一个大于小于号,那么 表示相反的符号。
设 为 中以 结尾的子序列在 中能匹配的最长前缀长度。
下证,存在一个下标子序列 使得 , 能够匹配 。
假设 为 字典序最小时对应的 ,因为 子序列个数有限,因此 存在。
若存在 使得 ,
假设 , 达成最大匹配时子序列为 。
那么 $b_{k}\; s_{k+1}\;b_{k+1}\;s_{k+2}\cdots b_{r-1}\;s_{r}\;b_{r}$,且 $b_r=t_k \;s_{k+1}\; t_{k+1}\;s_{k+2}\;\cdots s_{l}\;t_{l} $。
下证 存在一个长度为 或 的子序列能够匹配 或 。
若 , 不成立。
那么分两种情况,。
那么 ,即 ,于是 中必存在一个前缀使得 ,且 $s_{k+1}=s_{k+2}=\cdots =s_{l}=s_{l+1}\cdots s_{d-1}=\hat{s_d}$,由传递性可知 $t_l\;s_{l}\;b_{l}\;s_{l+1}\; b_{l+1} \cdots s_{d-1}\;b_{d-1}$ 可以推出 ,又 那么 ,于是存在一个以 结尾的子序列可以匹配 的前缀长度为 矛盾!
否则存在相邻两项 ,那么 ,,,,于是 $b_{d-1}\;\hat{s_{d}}\;t_{d}\;s_{d+1}\;t_{d+1}\;s_{d+1}\;b_{d}\;\hat{s_{d}}\;b_{d-1}$。
由 可知中间四个符号都相同,那么 矛盾!
所以 ,使得 。
那么此时把 接到 后面也是一组合法的解,此时 $x^{\prime}_{f_i},x^{\prime}_{f_i-1},\cdots x^{\prime}_0$ 的字典序更小,因为 变小了而 均没变化。
与假设矛盾!
若存在 使得 ,那么这时令 , 达成最大匹配时子序列为 。
与上面同理,只有 时会推出 ,而 ,由 得出 ,矛盾!
命题成立。
因此我们可以直接用树状数组维护 dp 值。
Code
#include <cstdio> #include <algorithm> using namespace std; constexpr int N=300010; int b1[N],b2[N]; void upd(int *b,int x,int v){for(;x<N;x+=(x&(-x))) b[x]=max(b[x],v);} int qry(int *b,int x){int ans=0;for(;x;x-=(x&(-x))) ans=max(ans,b[x]);return ans;} char s[N];int n,a[N]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]);scanf("%s",s+1);int ans=0; for(int i=1;i<=n;++i){ int f=max(qry(b1,a[i]-1),qry(b2,n-a[i]));ans=max(ans,f); if(s[f+1]=='U') upd(b1,a[i],f+1);else upd(b2,n-a[i]+1,f+1); } printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 7617
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者