难道是用指针这题必炸吗 /yiw
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <iostream>
#include <list>
#include <queue>
#include <set>
#include <vector>
typedef long long ll;
template <typename T1, typename T2, typename T3>
T1 qpow(T1 a, T2 b, T3 p)
{
T1 ans = 1, base = a;
for (; b; b >>= 1)
{
if (b & 1)
ans = (ans * base) % p;
base = (base * base) % p;
}
return ans;
}
namespace G
{
constexpr int maxn = 1e6 + 100;
struct edge
{
int w, to;
edge* nxt = nullptr;
} e[maxn << 1];
edge* head[maxn];
int cnt = 1;
void add(int u, int v)
{
auto tmp = e + (++cnt);
tmp->to = v;
tmp->nxt = head[u];
head[u] = e + cnt;
}
void add(int u, int v, int w)
{
auto tmp = e + (++cnt);
tmp->to = v;
tmp->w = w;
tmp->nxt = head[u];
head[u] = e + cnt;
}
void Add(int u, int v, int w)
{
add(u, v, w), add(v, u, w);
}
void Add(int u, int v)
{
add(u, v), add(v, u);
}
}; // namespace G
//串最长长度
constexpr int maxn = 1e6 + 100;
namespace SAM
{
std::string s;
struct SAM_BASE;
typedef SAM_BASE Node;
typedef Node* lpNode;
struct SAM_BASE
{
int len;
lpNode link;
__gnu_pbds::gp_hash_table<char, lpNode> nxt;
};
lpNode root;
struct sam
{
Node st[maxn << 1];
lpNode last;
int siz;
void init();
void build();
void extend(char);
sam()
{
root = st;
}
} am;
void sam::init()
{
root->len = 0;
root->link = nullptr;
++siz;
last = root;
}
void sam::extend(char c)
{
lpNode cur = st + (++siz);
if (last != nullptr) cur->len = last->len + 1;
auto p = last;
while (p != nullptr && p->nxt.find(c) == p->nxt.end())
{
p->nxt[c] = cur;
p = p->link;
}
if (p == nullptr)
cur->link = root;
else
{
auto q = p->nxt[c];
q = q == nullptr ? root : q;
if (p->len + 1 == q->len)
cur->link = q;
else
{
auto clone = st + (++siz);
clone->len = p->len + 1;
clone->nxt = q->nxt;
clone->link = q->link;
while (p != nullptr && p->nxt[c] == q)
{
p->nxt[c] = clone;
p = p->link;
}
q->link = cur->link = clone;
}
}
last = cur;
}
void sam::build()
{
std::cin >> s;
this->init();
for (auto p : s)
this->extend(p);
}
} // namespace SAM
int size[maxn];
int res = -1;
void buildG()
{
using namespace SAM;
for (int i = 2; i <= am.siz; ++i)
G::add(am.st[i].link - am.st, i);
std::fill_n(size + 1, maxn, 1);
}
void dfs(int u)
{
using namespace G;
for (auto p = head[u]; p != nullptr; p = p->nxt)
dfs(p->to), size[u] += size[p->to];
if (size[u] != 1) res = std::max(res, size[u] * SAM::am.st[u].len);
}
int canselSync = (std::ios::sync_with_stdio(0),
std::cin.tie(0),
std::cout.tie(), 0);
signed main()
{
//============================================
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
int t1 = std::clock();
#endif
//============================================
SAM::am.build();
buildG();
dfs(0);
std::cout << res << std::endl;
//============================================
#ifndef ONLINE_JUDGE
int t2 = std::clock();
std::cout << "\n"
<< (t2 - t1) / double(CLOCKS_PER_SEC) << "s" << std::endl;
#endif
//============================================
return 0;
}