QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#58032 | #4844. Positive String | MIT01# | ML | 0ms | 0kb | C++17 | 4.0kb | 2022-10-24 11:23:46 | 2022-10-24 11:23:47 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb emplace_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
typedef long long LL;
const int oo = 0x3f3f3f3f;
const int maxn = 200010;
int n;
int s[maxn * 2 + 5];
int tot = 0;
map<int, int> go[maxn * 4 + 5];
int fa[maxn * 4 + 5];
int Max[maxn * 4 + 5];
int rt = 0;
inline int add(int p, int w)
{
if (go[p][w] && Max[go[p][w]] == Max[p] + 1) return go[p][w];
int np = tot++;
fa[np] = -1;
Max[np] = Max[p] + 1;
while (p != -1 && !go[p][w]) go[p][w] = np, p = fa[p];
if (p == -1) fa[np] = rt;
else
{
int q = go[p][w];
if (Max[q] == Max[p] + 1) fa[np] = q;
else
{
int nq = tot++;
fa[nq] = -1;
Max[nq] = Max[p] + 1;
go[nq] = go[q];
fa[nq] = fa[q];
fa[np] = fa[q] = nq;
while (p != -1 && go[p][w] == q)
{
go[p][w] = nq;
p = fa[p];
}
}
}
return np;
}
struct node
{
node *c[2], *p;
LL sum;
int cnt;
int w;
int sumw;
int label;
node(): p(NULL), sum(0), cnt(0), w(0), sumw(0), label(0)
{
memset(c, 0, sizeof c);
}
void update()
{
sumw = w;
sum = (LL)cnt * w;
REP(i, 0, 2) if (c[i])
{
sumw += c[i]->sumw;
sum += c[i]->sum;
}
}
void flag_label(int x)
{
cnt += x;
label += x;
sum += (LL)x * sumw;
}
void push_down()
{
if (label)
{
REP(i, 0, 2)
if (c[i])
{
c[i]->flag_label(label);
}
label = 0;
}
}
int get_pos()
{
if (!this || !p) return 2;
REP(i, 0, 2) if (p->c[i] == this) return i;
return 2;
}
bool is_root()
{
return get_pos() >= 2;
}
void setc(node *u, int v)
{
if (this && v < 2) c[v] = u;
if (u) u->p = this;
}
void rotate()
{
node *tmp = this->p;
bool mark = get_pos();
tmp->p->setc(this, tmp->get_pos());
tmp->setc(c[mark ^ 1], mark);
setc(tmp, mark ^ 1);
tmp->update();
}
void relax()
{
static node *tmp[maxn + 5];
int top = 0;
node *u = this;
while (!u->is_root()) tmp[top++] = u, u = u->p;
u->push_down();
while (top)
{
tmp[--top]->push_down();
}
}
void splay()
{
relax();
for ( ; !is_root(); rotate())
if (!p->is_root()) ((p->p->c[0] == p) == (p->c[0] == this) ? p : this)->rotate();
update();
}
node *access()
{
node *u = this, *v = NULL;
for ( ; u; v = u, u = u->p)
{
u->splay();
u->setc(v, 1);
u->update();
}
splay();
return v;
}
};
int where[maxn * 2 + 5];
node nd[27][maxn * 4 + 5];
inline LL query(int x)
{
int tmp = where[x];
LL ret = 0;
for (int i = s[x]; i > 0; i -= i & -i)
{
nd[i][tmp].access();
ret += nd[i][tmp].sum;
}
return ret;
}
inline void add(int x)
{
int tmp = where[x];
for (int i = s[x] + 1; i <= 26; i += i & -i)
{
nd[i][tmp].access();
nd[i][tmp].flag_label(1);
}
}
int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
static char ss[maxn + 5];
scanf("%s", ss);
n = strlen(ss);
REP(i, 0, n) s[i] = ss[i] - 'a';
s[n] = 26;
REP(i, 0, n) s[2 * n - i] = ss[i] - 'a';
n = 2 * n + 1;
tot = 1;
fa[0] = -1;
int cur = 0;
REP(i, 0, n)
{
where[i] = cur;
cur = add(cur, s[i]);
}
where[n] = cur;
// REP(i, 0, tot) if (~fa[i]) children[fa[i]].pb(i);
// dfs(0)
REP(j, 1, 27)
{
REP(i, 0, tot)
{
if (~fa[i]) nd[j][i].p = nd[j] + fa[i];
nd[j][i].w = (Max[i] + 1) - (~fa[i] ? (Max[fa[i]] + 1) : 0);
nd[j][i].update();
}
}
LL ans = 0;
int j = n >> 1;
for (int i = (n >> 1) - 1; i >= 0; --i)
{
ans += query(i);
++j;
if (j < n)
{
add(j);
}
}
printf("%lld\n", ans);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Memory Limit Exceeded
input:
jjikkollp