题目描述
话说世界上有很多超级英雄:蝙蝠侠,蜘蛛侠,超人,名字都写不出来的人
等等。在他们之中有一个叫Kickass。今天他想模仿蜘蛛侠,所以他选择了一排
高楼来跳。
具体来说,他选择了一列N 幢高楼,从左到右标号为1 到N。一开始他在
第K 幢高楼。不幸的是,Kickass 能力非常有限,只能跳到向左或向右相邻的高
楼,而且他要跳到的楼的高度必须不能大于他现在处在的楼的高度。Kickass 不
想自己看起来很渣渣,所以他在一些高楼顶部放了蹦床,从这些高楼起跳,能跳
到任何其他的高楼,不管要跳到的高楼在哪里或是多高。
你的任务是找到Kickass 在第K 高楼起跳能跳到的最多不同的高楼数。如果
Kickass 跳到一幢高楼超过一次,我们只会算一次。并且,即使Kickass 没有重新
跳到,第K 幢高楼还是要算入答案。
输入
第一行输入两个数:高楼数N(3<=N<=300,000),起跳位置K(1<=K<=N)。
第二行包括N 个小于10^6 的整数,表示1 到N 高楼的高度。
第三行包括一行N 个字符’.’或’T’。如果第i 个字符为’T’,则第i 幢楼上有蹦床。
spider.in
10 1
10 7 3 1 1 9 8 2 4 10
..T..T....
输出
输出一行,最多可以跳到的楼数。
spider.out
7
样例输入
6 4 12 16 16 16 14 14 .T....
样例输出
5
提示
【样例解释】
第二个样例Kickass 经过高楼的顺序:
1 -> 2 -> 3 -> 6 -> 10 -> 9 -> 8
题解:
好题。
大概就是注意下相邻高楼之间的关系,以及从弹簧处出发可以到所有高楼。
我们肯定不可能将弹簧直接和其他点直接搞上联系,所以我们考虑建一个虚点,表示弹簧可以经过这个点,跳到所有的点上。
然后,我们再考虑将虚点与每个点搞上联系。
对于这种模型,可以考虑直接tarjan缩点然后在TAG上跑最长路。
好吧,这种模型我写的还不够多,一下子没反应过来。
#include<bits/stdc++.h>
using namespace std;
#define in inline
#define re register
#define rep(i,a,b) for(re int i=a;i<=b;i++)
#define repd(i,a,b) for(re int i=a;i>=b;i++)
#define For(i,a,b) for(re int i=a;i<b;i++)
#define _(d) while(d(isdigit(ch=getchar())))
template<class T>in void g(T&t){T x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
const int N=3e5+233;
struct E{int to,nxt;}e[N*3];
vector<int>ee[N];
int head[N],tot,f[N],a[N],n,k,sz[N];char s[N];
in void ins(int x,int y){e[++tot]=E{y,head[x]};head[x]=tot;}
int dfn[N],low[N],c[N],cl,cnt,st[N],tp;
in void tarjan(int x){
dfn[x]=low[x]=++cl;st[++tp]=x;
for(int i=head[x];i;i=e[i].nxt){
if(!dfn[e[i].to]){
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}else if(!c[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
}
if(low[x]==dfn[x]){
++cnt;
while(1)
{int u=st[tp--];c[u]=cnt;sz[cnt]++;if(u==x) break;}
}
}
in int dfs(int x){
if(f[x]!=-1) return f[x];
f[x]=0;
For(i,0,ee[x].size()){
int V=ee[x][i];
f[x]=max(f[x],dfs(V));
}f[x]+=sz[x];return f[x];
}
int main(){
g(n),g(k);
rep(i,1,n) g(a[i]);
scanf("%s",s+1);
rep(i,1,n){
ins(n+1,i);
if(s[i]=='T') ins(i,n+1);
else{
if(i<n&&a[i]>=a[i+1]) ins(i,i+1);
if(i>1&&a[i]>=a[i-1]) ins(i,i-1);
}
}++n;memset(f,-1,sizeof(f));
rep(i,1,n) if(!dfn[i]) tarjan(i);sz[c[n]]--;
rep(x,1,n)
for(int i=head[x];i;i=e[i].nxt)
if(c[x]!=c[e[i].to]) ee[c[x]].push_back(c[e[i].to]);
return !printf("%d\n",dfs(c[k]));
}