[杭电多校第二场]1012 String Distance(lcs)

Posted ketchum

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[杭电多校第二场]1012 String Distance(lcs)相关的知识,希望对你有一定的参考价值。

技术图片

 

 

 

不难发现答案即为a[l, r]的长度加上b的长度减去2倍的a[l,r]与b的LCS。

那么难点就在于如何处理出每次询问的lcs了,这里仍然采用dp的思想。对于dp[i][j]代表b串前i个字符串与a[l,r]形成了长度为j的公共子序列时在a串中的最小下标位置。

那么不难得出转移方程1 :dp[i][j] = min(dp[i][j], dp[i+1][j]) 和 转移方程2:dp[i][j] = min(dp[i][j], a串中dp[i-1][j-1]后面第一个出现b[i]的位置),而某个位置后面第一个字符出现的位置显然可以用序列自动机直接得出。那么这样子复杂度就是26*n + q * m * m,你就可以快乐的ac了。具体实现见代码。

 

技术图片
#pragma GCC optimize("-Ofast","-funroll-all-loops")
//freopen("C://std/a.in","r",stdin);
//freopen("C://std/b.txt","w",stdout);
#include<bits/stdc++.h>
#define ll long long
#define PB push_back
#define endl ‘
‘
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) (x & (-x))
#define rep(i, a, b) for(int i = a ; i <= b ; ++ i)
#define per(i, a, b) for(int i = b ; i >= a ; -- i)
#define clr(a, b) memset(a, b, sizeof(a))
#define in insert
#define random(x) (rand()%x)
#define PII(x, y) make_pair(x, y)
#define fi first
#define se second
#define pi acos(-1)
#define re register
//std::ios::sync_with_stdio(false);
using namespace std;
const int maxn = 1e6 + 50;
const int N = 1e5 + 10;
const int M = N * 20;
const ll mod = 1e9 + 9;
int T, n, m;
int nxt[maxn][26], dp[30][30];
char a[maxn], b[maxn];
int solve(int l, int r){
    clr(dp, INF); dp[0][0] = l - 1;
    for(int i = 1 ; i <= m ; ++ i){
        dp[i][0] = l - 1;
        for(int j = 1 ; j <= i ; ++ j){
            dp[i][j] = min(dp[i-1][j],dp[i][j]);
            if(dp[i-1][j-1] < r)
            dp[i][j] = min(dp[i][j], nxt[dp[i-1][j-1]][b[i]-a]);
        }
    }
    per(i, 0, m){
        rep(j, i, m){
            if(dp[j][i] <= r) return i;
        }
    }
    return 0;
}
signed main(){
    cin >> T; int q, l, r;
    while(T --){
        scanf("%s", a + 1); n = strlen(a + 1);
        scanf("%s", b + 1); m = strlen(b + 1);
        scanf("%d", &q);
        clr(nxt, 0x3f);
        per(i, 1, n){
            for(int j = 0 ; j < 26 ; ++ j){
                nxt[i-1][j] = nxt[i][j];
            }
            nxt[i-1][a[i]-a] = i;
        }
        while(q --){
            scanf("%d %d", &l, &r);
            cout << r - l + 1 + m - solve(l, r) *  2 << endl;
        }
    }
    return 0;
}
View Code

 

以上是关于[杭电多校第二场]1012 String Distance(lcs)的主要内容,如果未能解决你的问题,请参考以下文章

2018杭电多校第二场1003(DFS,欧拉回路)

2020杭电多校第二场题解

2022杭电多校第二场 A.Static Query on Tree(树剖)

2022杭电多校第二场 A.Static Query on Tree(树剖)

2022杭电多校第二场 A.Static Query on Tree(树剖)

2022杭电多校第二场 A.Static Query on Tree