SP694 DISUBSTR - Distinct Substrings(洛谷 字典树)

题目链接:https://www.luogu.com.cn/problem/SP694
题意

  • t组测试样例,每组给一个字符串
  • 求该字符串本质不同的子串的个数
思路
  • 子串其实就是字符串后缀的前缀。比如给一个串是“abaab”,则"aa"是后缀“aab”的前缀。
  • 要算前缀种数,就要马上想到字典树啦,它可以很方便的求出字符串前缀的种数。
  • 不过这道题把时间卡的死死的,初始化的时候要注意,还有就是字符串得定义成char类型。
AC代码
#include #define LL long long #define sc(a) scanf("%d", &a) #define sc2(a, b) scanf("%d%d", &a, &b) #define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c) #define scl(a) scanf("%lld", &a) #define scl2(a, b) scanf("%lld%lld", &a, &b) #define ss(a) scanf("%s", a) #define mem(a, b) memset(a, b, sizeof(a)) #define PII pair using namespace std; const int maxn = 1e6 + 5; const int mod = 1e9 + 7; int t[maxn][127]; int tot = 1, n; char s[maxn]; void add_node(int i, int j) { for (int k = j; k < n; k++) { if (!t[i][s[k]]) t[i][s[k]] = ++tot; i = t[i][s[k]]; } } int main() { int T; scanf("%d", &T); while (T--) { tot = 1; ss(s); n = strlen(s); for (int i = 0; i < n; i++) //添加后缀字符串 { add_node(1, i); } cout << tot - 1 << endl; //还要减去空串 for (int i = 1; i <= tot + 5; i++) //数组初始化,如果直接memset会tle for (int j = 1; j < 127; j++) t[i][j] = 0; } system("pause"); return 0; }

【SP694 DISUBSTR - Distinct Substrings(洛谷 字典树)】

    推荐阅读