Submission #68582836
Source Code Expand
/*
Template Version: 1.0.0 - 20220620
Author: Nguyen Tan Bao
Status:
Idea:
*/
#include <bits/stdc++.h>
#define FI first
#define SE second
#define ALL(a) a.begin(), a.end()
#define SZ(a) int((a).size())
#define MS(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define TRAV(x, a) for (auto &x : a)
using namespace std;
using ll = long long; using ld = double;
using pi = pair<int, int>; using pl = pair<ll, ll>; using pd = pair<ld, ld>;
using cd = complex<ld>; using vcd = vector<cd>;
using vi = vector<int>; using vl = vector<ll>;
using vd = vector<ld>; using vs = vector<string>;
using vpi = vector<pi>; using vpl = vector<pl>; using vpd = vector<pd>; // vector<pair>
template<class T> using min_pq = priority_queue<T, vector<T>, greater<T> >;
template<class T> inline int ckmin(T& a, const T& val) { return val < a ? a = val, 1 : 0; }
template<class T> inline int ckmax(T& a, const T& val) { return a < val ? a = val, 1 : 0; }
template<class T> void remDup(vector<T>& v) { sort(ALL(v)); v.erase(unique(ALL(v)), end(v)); }
constexpr int pct(int x) { return __builtin_popcount(x); } // # of bits set
constexpr int bits(int x) { return x == 0 ? 0 : 31-__builtin_clz(x); } // floor(log2(x))
constexpr int p2(int x) { return 1<<x; }
constexpr int msk2(int x) { return p2(x)-1; }
ll ceilDiv(ll a, ll b) { return a / b + ((a ^ b) > 0 && a % b); } // divide a by b rounded up
ll floorDiv(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); } // divide a by b rounded down
void setPrec(int x) { cout << fixed << setprecision(x); }
// TO_STRING
#define ts to_string
string ts(char c) { return string(1, c); }
string ts(const char* s) { return (string) s; }
string ts(string s) { return s; }
string ts(bool b) { return (b ? "true" : "false"); }
template<class T> using V = vector<T>;
template<class T> string ts(complex<T> c);
string ts(V<bool> v);
template<size_t sz> string ts(bitset<sz> b);
template<class T> string ts(T v);
template<class T, class U> string ts(pair<T,U> p);
template<class ...U> string ts(tuple<U...> u);
template<class T> string ts(complex<T> c) { stringstream ss; ss << c; return ss.str(); }
string ts(V<bool> v) {string res = "{"; FOR(i,0,SZ(v)-1) res += char('0'+v[i]); res += "}"; return res; }
template<size_t sz> string ts(bitset<sz> b) { string res = ""; FOR(i,0,SZ(b)-1) res += char('0'+b[i]); return res; }
template<class T> string ts(T v) { // containers with begin(), end()
bool fst = 1; string res = "";
for (const auto& x: v) { if (!fst) res += " "; fst = 0; res += ts(x); }
return res;
}
template<class T, class U> string ts(pair<T,U> p) { return "(" + ts(p.FI) + ", " + ts(p.SE) + ")"; }
template<size_t i, class T> string print_tuple_utils(const T& tup) { if constexpr(i == tuple_size<T>::value) return ")"; else return (i ? ", " : "(") + ts(get<i>(tup)) + print_tuple_utils<i + 1, T>(tup); }
template<class ...U> string ts(tuple<U...> u) { return print_tuple_utils<0, tuple<U...>>(u); }
// OUTPUT
template<class T> void pr(T x) { cout << ts(x); }
template<class T, class ...U> void pr(const T& t, const U&... u) { pr(t); pr(u...); }
void ps() { pr("\n"); } // print w/ spaces
template<class T, class ...U> void ps(const T& t, const U&... u) { pr(t); if (sizeof...(u)) pr(" "); ps(u...); }
// DEBUG
void DBG() { cerr << "]" << endl; }
template<class T, class ...U> void DBG(const T& t, const U&... u) { cerr << ts(t); if (sizeof...(u)) cerr << ", "; DBG(u...); }
#ifdef LOCAL_DEBUG
#define CONCAT(x, y) x##y
#define with_level setw(__db_level * 2) << setfill(' ') << "" << setw(0)
#define dbg(...) cerr << with_level << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#define chk(...) if (!(__VA_ARGS__)) cerr << setw(__db_level * 2) << setfill(' ') << "" << setw(0) << "Line(" << __LINE__ << ") -> function(" << __FUNCTION__ << ") -> CHK FAILED: (" << #__VA_ARGS__ << ")" << "\n", exit(0);
#define db_block() debug_block CONCAT(dbbl, __LINE__)
int __db_level = 0;
struct debug_block {
debug_block() { cerr << with_level << "{" << endl; ++__db_level; }
~debug_block() { --__db_level; cerr << with_level << "}" << endl; }
};
#else
#define dbg(...) 0
#define chk(...) 0
#define db_block() 0
#endif
const ld PI = acos(-1.0);
const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
const ld EPS = 1e-9;
const ll MODBASE = 998244353;
const int INF = 0x3f3f3f3f;
const int MAXN = 8;
const int MAXL = 101;
const int MAXK = 16;
const int MAXQ = 200010;
template<int MOD> struct mint {
static const int mod = MOD;
int v; explicit operator int() const { return v; } // explicit -> don't silently convert to int
mint() { v = 0; }
mint(ll _v) { v = int((-MOD < _v && _v < MOD) ? _v : _v % MOD);
if (v < 0) v += MOD; }
friend bool operator==(const mint& a, const mint& b) {
return a.v == b.v; }
friend bool operator!=(const mint& a, const mint& b) {
return !(a == b); }
friend bool operator<(const mint& a, const mint& b) {
return a.v < b.v; }
friend string ts(mint a) { return ts(a.v); }
mint& operator+=(const mint& m) {
if ((v += m.v) >= MOD) v -= MOD;
return *this; }
mint& operator-=(const mint& m) {
if ((v -= m.v) < 0) v += MOD;
return *this; }
mint& operator*=(const mint& m) {
v = int((ll) v * m.v % MOD); return *this; }
mint& operator/=(const mint& m) { return (*this) *= inv(m); }
friend mint pow(mint a, ll p) {
mint ans = 1; assert(p >= 0);
for (; p; p /= 2, a *= a) if (p&1) ans *= a;
return ans; }
friend mint inv(const mint& a) { assert(a.v != 0);
return pow(a,MOD-2); }
mint operator-() const { return mint(-v); }
mint& operator++() { return *this += 1; }
mint& operator--() { return *this -= 1; }
friend mint operator+(mint a, const mint& b) { return a += b; }
friend mint operator-(mint a, const mint& b) { return a -= b; }
friend mint operator*(mint a, const mint& b) { return a *= b; }
friend mint operator/(mint a, const mint& b) { return a /= b; }
};
typedef mint<MODBASE> mi;
typedef vector<mi> vmi;
typedef pair<mi,mi> pmi;
typedef vector<pmi> vpmi;
struct AhoCorasick {
struct Node {
int next[26], link, mask;
Node() {
fill(begin(next), end(next), -1);
link = -1;
mask = 0;
}
};
vector<Node> trie;
AhoCorasick() { trie.emplace_back(); }
void insert(const string &s, int idx) {
int v = 0;
for (char ch : s) {
int c = ch - 'a';
if (trie[v].next[c] == -1) {
trie[v].next[c] = SZ(trie);
trie.emplace_back();
}
v = trie[v].next[c];
}
trie[v].mask |= (1<<idx);
}
void build() {
queue<int> q;
trie[0].link = 0;
FOR(c,0,25) {
int u = trie[0].next[c];
if (u != -1) {
trie[u].link = 0;
q.push(u);
} else {
trie[0].next[c] = 0;
}
}
while (SZ(q)) {
int v = q.front(); q.pop();
trie[v].mask |= trie[trie[v].link].mask;
FOR(c,0,25) {
int u = trie[v].next[c];
if (u != -1) {
trie[u].link = trie[trie[v].link].next[c];
q.push(u);
} else {
trie[v].next[c] = trie[trie[v].link].next[c];
}
}
}
}
};
int n, L;
string s[MAXN];
mi dp[MAXL][MAXN * 11][1<<MAXN];
mi solve() {
// find number of strings of length L with all s[i] as substrings
AhoCorasick ac;
FOR(i,0,n-1) ac.insert(s[i], i);
ac.build();
int acSize = ac.trie.size();
dp[0][0][0] = 1;
FOR(i,0,L-1) {
FOR(j,0,acSize-1) {
FOR(mask,0,(1<<n)-1) {
if (int(dp[i][j][mask]) == 0) continue;
FOR(c,0,25) {
int nextNode = ac.trie[j].next[c];
int nextMask = mask | ac.trie[nextNode].mask;
dp[i+1][nextNode][nextMask] += dp[i][j][mask];
}
}
}
}
mi res = 0;
FOR(i,0,acSize-1) res += dp[L][i][(1<<n)-1];
return res;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
cin >> n >> L;
FOR(i,0,n-1) cin >> s[i];
cout << int(solve());
return 0;
}
Submission Info
| Submission Time |
|
| Task |
F - All Included |
| User |
farmerboy |
| Language |
C++ 20 (gcc 12.2) |
| Score |
550 |
| Code Size |
8874 Byte |
| Status |
AC |
| Exec Time |
71 ms |
| Memory |
12488 KiB |
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
550 / 550 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt |
| All |
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_test_00.txt, 01_test_01.txt, 01_test_02.txt, 01_test_03.txt, 01_test_04.txt, 01_test_05.txt, 01_test_06.txt, 01_test_07.txt, 01_test_08.txt, 01_test_09.txt, 01_test_10.txt, 01_test_11.txt, 01_test_12.txt, 01_test_13.txt, 01_test_14.txt, 01_test_15.txt, 01_test_16.txt, 01_test_17.txt, 01_test_18.txt, 01_test_19.txt, 01_test_20.txt, 01_test_21.txt, 01_test_22.txt, 01_test_23.txt, 01_test_24.txt, 01_test_25.txt, 01_test_26.txt, 01_test_27.txt, 01_test_28.txt, 01_test_29.txt, 01_test_30.txt, 01_test_31.txt, 01_test_32.txt |
| Case Name |
Status |
Exec Time |
Memory |
| 00_sample_00.txt |
AC |
5 ms |
12356 KiB |
| 00_sample_01.txt |
AC |
4 ms |
12360 KiB |
| 00_sample_02.txt |
AC |
6 ms |
12320 KiB |
| 01_test_00.txt |
AC |
24 ms |
12320 KiB |
| 01_test_01.txt |
AC |
55 ms |
12472 KiB |
| 01_test_02.txt |
AC |
48 ms |
12344 KiB |
| 01_test_03.txt |
AC |
17 ms |
12368 KiB |
| 01_test_04.txt |
AC |
59 ms |
12488 KiB |
| 01_test_05.txt |
AC |
56 ms |
12488 KiB |
| 01_test_06.txt |
AC |
19 ms |
12368 KiB |
| 01_test_07.txt |
AC |
57 ms |
12392 KiB |
| 01_test_08.txt |
AC |
54 ms |
12380 KiB |
| 01_test_09.txt |
AC |
42 ms |
12296 KiB |
| 01_test_10.txt |
AC |
51 ms |
12456 KiB |
| 01_test_11.txt |
AC |
53 ms |
12464 KiB |
| 01_test_12.txt |
AC |
41 ms |
12476 KiB |
| 01_test_13.txt |
AC |
59 ms |
12320 KiB |
| 01_test_14.txt |
AC |
65 ms |
12488 KiB |
| 01_test_15.txt |
AC |
69 ms |
12356 KiB |
| 01_test_16.txt |
AC |
64 ms |
12268 KiB |
| 01_test_17.txt |
AC |
68 ms |
12384 KiB |
| 01_test_18.txt |
AC |
41 ms |
12352 KiB |
| 01_test_19.txt |
AC |
65 ms |
12264 KiB |
| 01_test_20.txt |
AC |
6 ms |
12468 KiB |
| 01_test_21.txt |
AC |
7 ms |
12328 KiB |
| 01_test_22.txt |
AC |
7 ms |
12392 KiB |
| 01_test_23.txt |
AC |
11 ms |
12296 KiB |
| 01_test_24.txt |
AC |
7 ms |
12468 KiB |
| 01_test_25.txt |
AC |
10 ms |
12380 KiB |
| 01_test_26.txt |
AC |
6 ms |
12364 KiB |
| 01_test_27.txt |
AC |
12 ms |
12384 KiB |
| 01_test_28.txt |
AC |
5 ms |
12240 KiB |
| 01_test_29.txt |
AC |
5 ms |
12324 KiB |
| 01_test_30.txt |
AC |
5 ms |
12388 KiB |
| 01_test_31.txt |
AC |
71 ms |
12392 KiB |
| 01_test_32.txt |
AC |
18 ms |
12356 KiB |