UCSD ICPC Club Nov20 E

I didn’t solve this problem in the club.

There’s a straightforward dynamic progamming where $f[i][j]$ represents the minimum number of cuts required for $s[0..i]$ and $t[0..j]$ but this would obviously exceed the time limit.
A direct idea is swap the state $j$ and the result:
$\text{dp}[\text{pref}][\text{cnt}]$ represents the length of the longest prefix of $t$ that can be formed by dividing $s[0..\text{pref}]$ into $\text{cnt}$ parts. However this doesn’t solve the time issue, as the number of states is still $O(n^2)$.

Actually, the intermediate states are completely useless. What’s ultimately required is whether the complete $s$ can be cut into $t$, so some states can be skipped. When there is a common substring, it’s not necessary to update every substring length state, only the final state (the longest common substring length) matter. State transition equation:

$$dp[\text{pref}+1][\text{cnt}]=\max\{dp[\text{pref}][\text{cnt}]\}$$ $$dp[\text{pref}+\text{len}][\text{cnt}+1]=\max\{dp[\text{pref}][\text{cnt}]+\text{len}\}$$

Where len represents the length of the longest common substring starting from $\text{pref} + 1$, and use string double hashing and binary search, total time $O(nx\log)$.

My initial idea was to add an extra dimension to dp, indicating whether the last cut was made at the far right, but this is actually a redundant state, regardless of where the last cut was made, the current state would definitely be updated by some previous states.

// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x),__VA_ARGS__})
#define cmax(x,...) x=max({(x),__VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define uint unsigned long long
#define MAXN 200010

template <char F, int B> struct strdhash {
    const pair<int, int> M = {999999893, 999999739};
    string s;
    int len;
    vector<pair<int, int>> pw, hs;
    strdhash(string S): s(S), len(S.size()) {
        pw.assign(len, {0, 0});
        pw[0] = {1, 1};
        rep(i, 1, len) pw[i].first = pw[i-1].first * B % M.first, pw[i].second = pw[i-1].second * B % M.second;
        hs.assign(len+1, {0, 0});
        rep(i, 0, len) hs[i+1].first = (hs[i].first * B + s[i] - F) % M.first, hs[i+1].second = (hs[i].second * B + s[i] - F) % M.second;
    }
    pair<int, int> hash(int l, int r) {
        if (!l) return hs[r+1];
        pair<int, int> res;
        res.first = (hs[r+1].first - hs[l].first * pw[r-l+1].first % M.first + M.first) % M.first;
        res.second = (hs[r+1].second - hs[l].second * pw[r-l+1].second % M.second + M.second) % M.second;
        return res;
    }
};

int32_t main() {
    ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

    int n, m, x;
    string s, t;
    cin >> n >> s >> m >> t >> x;
    s = "#" + s, t = "@" + t;
    strdhash hs = strdhash<'a', 26>(s);
    strdhash ht = strdhash<'a', 26>(t);
    vector<vector<int>> dp(n+1, vector<int>(x+2, 0));
    auto strc = [&](int S, int T, int len) {
        return hs.hash(S, S+len-1) == ht.hash(T, T+len-1);
    };
    auto bs = [&](int S, int T) {
        int l = 0, r = min(n-S+1, m-T+1);
        int ans = -1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (strc(S, T, mid)) ans = mid, l = mid + 1;
            else r = mid - 1;
        }
        return ans;
    };
    rep(i, 0, n) {
        rep(j, 0, x+1) {
            cmax(dp[i+1][j], dp[i][j]);
            int len = bs(i+1, dp[i][j]+1);
            if (~len) cmax(dp[i+len][j+1], dp[i][j] + len);
        }
    }
    cout << (dp[n][x] == m ? "YES" : "NO") << endl;

    return 0;
}

Comments

  1. 4 weeks ago
    2025-12-06 2:22:23

    Hey, I found festwinn! They seem to be having a special event. Check what are they selling and buy it quick! festwinn

  2. 2 weeks ago
    2025-12-19 13:37:16

    Bong88org is my go-to when the main site is acting up. Always a smooth experience, no lag or weird glitches. Trust me, it’s a lifesaver! bong88org

  3. 2 days ago
    2025-12-29 6:05:25

    Alright folks, mcgamesbet.info…seems like a combo of gaming and betting? What’s the deal? Are the odds any good on this site or is it just another trap? Would love to hear if anyone’s actually won something here. mcgamesbet

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Previous
Next