码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-07-25 11:28:59      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:false   return   i+1   mes   rand   转移   its   image   序列   

技术图片

 

 

 

不难发现答案即为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 ‘\n‘
#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)

标签:false   return   i+1   mes   rand   转移   its   image   序列   

原文地址:https://www.cnblogs.com/Ketchum/p/13375772.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!