[题解]2024 ICPC香港区域赛-LR String

  • Sources:K- LR String
  • Abstract:给定仅由LR构成的原字符串 S ( 1 ≤ ∣ S ∣ ≤ 5 × 1 0 5 ) S(1\le |S|\le5\times 10^5) S(1S5×105),其中L可删除其左侧字符,R可删除其右侧字符。给出 q ( 1 ≤ q ≤ 5 × 1 0 5 ) q(1\le q\le5\times 10^5) q(1q5×105)组询问,每次询问包含一个字符串 T ( 1 ≤ ∣ T i ∣ ≤ ∣ S ∣ ) T(1\le |T_i|\le |S|) T(1TiS),判断 T T T是否经由 S S S修改得到。( ∑ ( ∣ S ∣ + q + ∣ T i ∣ ) ≤ 1 0 6 \sum(|S|+q+|T_i|)\le 10^6 (S+q+Ti)106)
  • Keyword:字符串(签到题)
  • Solution:注意到 S S S中,当L出现在开头或R出现在末尾时,其将永远无法删除,因此当s.front()=='L'&&s.front()!=t.front()s.back()=='R'&&s.back()!=t.back()可直接判定无解。由于 T T T一定为 S S S删除某些字符得到,因此问题转换为判定 T T T是否为 S S S的子序列。注意到数据范围非常大,需设计 O ( n ) O(n) O(n)的算法判断子序列。
  • Code:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define endl "\n"
const int INF=__INT_MAX__;
void solve(){
    string s;cin>>s;
    vector<int>nxt_l(s.size(),INF),nxt_r(s.size(),INF);//S中每个字符的下个L/R位置表
    int l=INF,r=INF;
    for(int i=s.size()-1;i>=0;i--){//倒序遍历S进行预处理
        nxt_l[i]=l,nxt_r[i]=r;
        if(s[i]=='L') l=i;
        else r=i;
    }
    int q;cin>>q;
    while(q--){
        string t;cin>>t;
        bool ok=1;
        if ((s[0]=='L'&&s[0]!=t[0])||(s[s.size()-1]=='R'&&t[t.size()-1]!=s[s.size()-1])) {//2个特例
            cout<<"NO"<<'\n';
            continue;
        }
        int idx=(t[0]=='L')?l:r;//预处理后l/r即为S中首个L/R的位置
        if (idx>=s.size()) {
            cout<<"NO"<<'\n';
            continue;
        }
        for (int i=1;i<t.size();i++) {
            idx=(t[i]=='L')?nxt_l[idx]:nxt_r[idx];
            if (idx>=s.size()) {
                ok=0;
                break;
            }
        }
        if(ok) cout<<"YES"<<'\n';
        else cout<<"NO"<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--) solve();
    return 0;
}
posted @   椰萝Yerosius  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示