当前位置: 首页 > news >正文

甘肃嘉峪关建设局网站seo排名哪家有名

甘肃嘉峪关建设局网站,seo排名哪家有名,深圳做网站公司有哪些,机械加工厂字符串题 题目链接:YBT2023寒假Day14 C 题目大意 对于一个字符串 S 定义 F(S) 是 fail 树上除了 0 点其它点的深度和。 G(S) 是 S 每个子串 S’ 的 F(S’) 之和。 然后一个空串,每次在后面加一个字符,要你维护这个串的 G 值。 思路 考虑…

字符串题

题目链接:YBT2023寒假Day14 C

题目大意

对于一个字符串 S 定义 F(S) 是 fail 树上除了 0 点其它点的深度和。
G(S) 是 S 每个子串 S’ 的 F(S’) 之和。
然后一个空串,每次在后面加一个字符,要你维护这个串的 G 值。

思路

考虑把 G(S[1,x])G(S[1,x])G(S[1,x]) 值差分一下,会发现 G(S[1,i])−G(S[1,i−1])G(S[1,i])-G(S[1,i-1])G(S[1,i])G(S[1,i1]) 的值其实是以 iii 为结尾的子串的 FFF 值之和。
那从子串变成了一个后缀,看起来就可做很多了,考虑怎么算。

那我们看 fail 树性质,一个字符串 SSSjjjiii 的祖先当且仅当 S[1,j]=S[i−j+1,i]S[1,j]=S[i-j+1,i]S[1,j]=S[ij+1,i]
F(S)F(S)F(S) 就是满足 S[1,j]=S[i−j+1]S[1,j]=S[i-j+1]S[1,j]=S[ij+1]1⩽j<i1\leqslant j<i1j<i(i,j)(i,j)(i,j) 对数。
那也就是在 SSS 里面选一个前缀,再选一个非前缀,它们相等的方案数。

注意到我们要求的是以 iii 结尾的 FFF 值之和,那开头就不固定,结尾是固定的。
FFF 值是选一个前缀,再一个非前缀,那这个是开头固定,结尾不固定。
那你这个开头固定放在开头不固定里,它不固定了,你这个结尾不固定在结尾固定里面肯定也是不固定。
所以头尾都不固定,只需要两个不是同一个位置的字符串相等即可。
那答案就是所有本质不同的子串的出现次数 xxx(x2)\binom{x}{2}(2x) 之和。


那注意到不需要在线,我们可以先建出最后的后缀树。
那我们用一个 dxd_xdx 表示每个点 xxx 对于子串的出现次数。
那插入就是把它到祖先路径的 dxd_xdx 加一,询问就是所有点的 endpos 大小乘 (dx2)\binom{d_x}{2}(2dx)
那这个维护这个和不难,我们记录着这个和 sumsumsum,每次要插入的时候,每个新贡献的值就是它 endpos 集合大小乘上 dxd_xdx(这个 dxd_xdx 还没加 111),然后你再把 dxd_xdx 加一。
那这个是路径加值,路径求和,直接树链剖分线段树维护即可。
复杂度 O(nlog⁡2n)O(n\log ^2n)O(nlog2n)


ex:
如果强制在线,我们也可以用 LCT 来维护这棵树,那就也是同样的操作,复杂度 O(nlog⁡n)O(n\log n)O(nlogn)

代码

#include<cstdio>
#include<vector>
#define ll long long
#define mo 1000000007using namespace std;const ll N = 4e5 + 100;
ll n, fa[N], sz[N], son[N], dfn[N], top[N], dy[N];
ll lst = 1, tot = 1, pla[N]; 
char s[N];struct node {ll son[26], len, fa;
}d[N];struct XD_tree {ll num[N << 2], f[N << 2], lzy[N << 2];void up(ll now) {num[now] = (num[now << 1] + num[now << 1 | 1]) % mo;f[now] = (f[now << 1] + f[now << 1 | 1]) % mo;}void downa(ll now, ll x) {(f[now] += x * num[now] % mo) %= mo;(lzy[now] += x) %= mo;}void down(ll now) {if (lzy[now]) {downa(now << 1, lzy[now]); downa(now << 1 | 1, lzy[now]);lzy[now] = 0;}}void build(ll now, ll l, ll r) {if (l == r) {num[now] = d[dy[l]].len - d[d[dy[l]].fa].len;return ;}ll mid = (l + r) >> 1;build(now << 1, l, mid); build(now << 1 | 1, mid + 1, r);up(now);}void update(ll now, ll l, ll r, ll L, ll R, ll x) {if (L <= l && r <= R) {downa(now, x); return ;}ll mid = (l + r) >> 1; down(now);if (L <= mid) update(now << 1, l, mid, L, R, x);if (mid < R) update(now << 1 | 1, mid + 1, r, L, R, x);up(now);}ll query(ll now, ll l, ll r, ll L, ll R) {if (L <= l && r <= R) return f[now];ll mid = (l + r) >> 1; down(now); ll re = 0;if (L <= mid) (re += query(now << 1, l, mid, L, R)) %= mo;if (mid < R) (re += query(now << 1 | 1, mid + 1, r, L, R)) %= mo;return re;}
}T;struct SLPF {vector <ll> G[N];void add(ll x, ll y) {G[x].push_back(y);}void dfs0(ll now, ll father) {fa[now] = father; sz[now] = 1;for (ll i = 0; i < G[now].size(); i++) {ll x = G[now][i];dfs0(x, now); sz[now] += sz[x];if (sz[x] > sz[son[now]]) son[now] = x;}}void dfs1(ll now, ll father) {dfn[now] = ++dfn[0]; dy[dfn[0]] = now;if (son[now]) {top[son[now]] = top[now]; dfs1(son[now], now);}for (ll i = 0; i < G[now].size(); i++) {ll x = G[now][i]; if (x == son[now]) continue;top[x] = x; dfs1(x, now);}}void build() {dfs0(1, 0); top[1] = 1; dfs1(1, 0);T.build(1, 1, tot);}void update_root(ll now) {while (now) {T.update(1, 1, tot, dfn[top[now]], dfn[now], 1);now = fa[top[now]];}}ll query_root(ll now) {ll re = 0;while (now) {(re += T.query(1, 1, tot, dfn[top[now]], dfn[now])) %= mo;now = fa[top[now]];}return re;}
}P;struct SAM {ll insert(ll x) {ll p = lst, np = ++tot; lst = np;d[np].len = d[p].len + 1;for (; p && !d[p].son[x]; p = d[p].fa) d[p].son[x] = np;if (!p) d[np].fa = 1;else {ll q = d[p].son[x];if (d[q].len == d[p].len + 1) d[np].fa = q;else {ll nq = ++tot; d[nq] = d[q];d[nq].len = d[p].len + 1;d[q].fa = d[np].fa = nq;for (; p && d[p].son[x] == q; p = d[p].fa) d[p].son[x] = nq;}}return np;}void build() {for (ll i = 2; i <= tot; i++) P.add(d[i].fa, i);}
}S;int main() {freopen("string.in", "r", stdin);freopen("string.out", "w", stdout);scanf("%lld", &n);scanf("%s", s + 1);for (ll i = 1; i <= n; i++) pla[i] = S.insert(s[i] - 'a');S.build(); P.build();ll sum = 0, ans = 0;for (ll i = 1; i <= n; i++) {(sum += P.query_root(pla[i])) %= mo;P.update_root(pla[i]);(ans += sum) %= mo;printf("%lld\n", ans);}return 0;
}
http://www.15wanjia.com/news/27841.html

相关文章:

  • 成都网站制作汕头张家界seo
  • 网站开发前端后端书籍推广方案流程
  • 东莞网站开发哪里找提供seo顾问服务适合的对象是
  • 对网站建设有什么样意见快手流量推广网站
  • ubuntu用wordpress肇庆seo排名外包
  • 做网站的数据库的步骤网站seo推广seo教程
  • 内在空间官网宁波seo免费优化软件
  • 微信营销的案例如何网站关键词优化
  • 义乌外贸网站建设公司网络优化方案
  • 深圳小程序开发官网杭州百度优化
  • 朝阳区网站建设网站策划是干什么的
  • 有关做能源的网站当下最流行的营销方式
  • 网站制作公司承担郑州外语网站建站优化
  • 表格制作excel优化seo软件
  • 河南多地启动恢复线下教学广州网站优化页面
  • wordpress 透明文章南京搜索引擎推广优化
  • 网站建设公众号小程序开发关键词广告
  • wordpress网站托管鲜花网络营销推广方案
  • 深圳网站制作公司兴田德润怎么样兰州seo实战优化
  • 安顺网站开发深圳全网营销平台排名
  • 重庆网站seo推广公司广东seo点击排名软件哪家好
  • 此网站域名三天更换推广项目的平台
  • 网站做板块地图的办法百度行发代理商
  • 中山外贸网站建设公司大连seo顾问
  • 展示用网站模板免费下载模板建站教程
  • 地方旅游网站模板百度推广账户优化方案
  • 培训网站系统建设方案百度seo培训公司
  • 网站开发方向学啥怎样做一个产品营销方案
  • 零基础网站建设视频教程优化公司排名
  • 如何用服务器搭建网站网站构建的基本流程