Kattis - subsequencesinsubstrings

题目大意:
给你一个串s
再给你一个串t
问你有多少个s的子串中非连续包含t的有多少个

思路:
首先只有s中只有单个t的序列的时候
比如s=mmamm,t=a
这时候(a左边字母加+1)×(a右边字母+1)的时候就是结果
因为每个mma,ma,a都对应右边有两个字母
再加上左边连续子串数量3就是答案
那么如果出现多种t序列的时候呢?
比如s=mamam,t=a
这种时候对于第一个a的贡献是2×4
第二个是4×2
但这个时候会发现有子串有重叠串
就是mamam,mama,amam,ama重复计算了两次
这时候其实我们就能发现计算的时候把下个t的开头减去上个t的开头乘上末尾部分就是一个t的贡献
接来下就是枚举的事情啦
(比赛的时候例子写少了emmm,找不到感觉,麻了)

代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <deque>
#include <string>
#include <math.h>
#include <string.h>
#include <cstdio>
#include <utility>
#define pf(x) (x)*(x)
#define lowerbit(x) x&(-x)
#define mid (l+r>>1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll mod=998244353;
string s;
int main()
{
    ios::sync_with_stdio(false),cin.tie(0);
    string t;
    cin>>s>>t;
    int l=-1,r=-1;
    int len1=s.size(),len2=t.size();
    ll ans=0;
    int st=-1;
    while(1){
        l=s.find(t[0],st+1);//从上个找到t的开头下标开始往下找
        if(l==-1)break;//找不到就说明没有了
        r=l;
        for(int i=1;i<len2;i++){
            r=s.find(t[i],r+1);
            if(r==-1)break;
        }
        if(r==-1)break;
        ans+=(l-st)*(len1-r);//(这个t的开头减去上个t的开头)乘上(字符串长度减去末尾)答案
        st=l;
    }
    cout<<ans<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值