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

常州网站建设套餐网络产品代理加盟

常州网站建设套餐,网络产品代理加盟,wordpress 主题 xiu,企业网站广告T1 放 CF *3400。。。。 虽然有一点点加强但是做法相同,按照这道题的题意来讲。 题意 给定 m m m 个模式串 t i t_i ti​,每个模式串有一个价值 v i v_i vi​。 同时给定一个长度为 n n n 的模板串 S S S。 q q q 次询问,每次询问给定…

T1 放 CF *3400。。。。
虽然有一点点加强但是做法相同,按照这道题的题意来讲。

题意

给定 m m m 个模式串 t i t_i ti,每个模式串有一个价值 v i v_i vi
同时给定一个长度为 n n n 的模板串 S S S q q q 次询问,每次询问给定 l , r l, r l,r,你需要求出 S l , r S_{l, r} Sl,r 中每个模式串的出现次数乘价值之和: ∑ i ( c n t i × v i ) \sum\limits_{i}(cnt_i \times v_i) i(cnti×vi)
强制在线。

1 ≤ n , m , q ≤ 10 6 1 \leq n, m, q \leq 10^6 1n,m,q106 ∑ ∣ t i ∣ ≤ 10 6 \sum|t_i| \leq 10^6 ti106

分析

首先看到多模式串匹配所以我们来考虑 A C A M ACAM ACAM。( A C AC AC 自动机)

不要因为学过 S A M SAM SAM 就只要看到字符串题就往 S A M SAM SAM 上想, S A M SAM SAM 在处理一个或多个字符串的子串信息时比较有优势,但是相对的它的结构更复杂或许拓展起来就比较难。像这道题所求信息只是简单的多模式串匹配,因此我们考虑 A C AC AC 自动机。

我们建出 t i t_i ti A C AC AC 自动机。将 S S S A C AC AC 自动机上匹配一遍,能求出以 S S S 的每个位置为结尾所有匹配的字符串的价值之和,记为 h i h_i hi。那么将 h i h_i hi 求前缀和得到 h i ′ h'_i hi,每次询问回答 h r ′ − h l − 1 ′ h'_r - h'_{l - 1} hrhl1

发现这个做法虽然很自然但是却并不正确,因为有可能一个 h i h_i hi 中包含了一个左端点不在 [ l , r ] [l, r] [l,r] 以内的字符串的贡献。我们尝试在这个做法上进行一些修改使它正确。

假设以位置 i i i 为结尾能匹配的最长模式串的编号为 g i g_i gi,我们找到 [ l , r ] [l, r] [l,r] 中最靠后的位置 p p p,满足 p − ∣ t g p ∣ + 1 ≤ l p - |t_{g_p}| + 1 \leq l ptgp+1l,那么对于 [ p + 1 , r ] [p + 1, r] [p+1,r],它们的贡献就等于 h r − h p h_r - h_p hrhp

对于 [ l , p ] [l, p] [l,p] 的贡献怎么算呢?
暴力的想法是我们对 S l , p S_{l, p} Sl,p A C AC AC 自动机上跑一遍匹配,过程中求出贡献,这显然复杂度不可接受。
但是注意到 S l , p S_{l, p} Sl,p 完全等于 t g p t_{g_p} tgp 长为 p − l + 1 p - l + 1 pl+1 的后缀,我们完全可以预处理所有 t i t_i ti 的后缀信息,这样就可以 O ( 1 ) O(1) O(1) 查询。

预处理所有 t i t_i ti 的后缀信息:将所有 t i t_i ti 的反串建 A C A M ACAM ACAM,然后对每个 t i t_i ti 从后往前跑一遍匹配即可。复杂度 O ( ∑ ∣ t i ∣ ) O(\sum |t_i|) O(ti)

每次询问用线段树二分找 p p p,复杂度 O ( m log ⁡ n ) O(m \log n) O(mlogn)

总复杂度 O ( ∑ ∣ t i ∣ + m log ⁡ n ) O(\sum |t_i| + m\log n) O(ti+mlogn)。代码很好写。

CODE:

// 把要求的东西拆成两部分,一部分可以直接算,另一部分可以转化到一个可以预处理的问题上 
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
char s[N], t[N];
int n, m, q, l[N], r[N], g[N]; // g[i] 表示 i 位置为结尾能匹配的最长 t 串的编号 
LL v[N], S[N], sum[N];
struct ACAM { int tr[N][26], fail[N], et[N], tot; // 初始节点从 0 开始 LL val[N];inline void ins(char *s, int idx, LL v) {int p = 0, len = strlen(s + 1);for(int i = 1; i <= len; i ++ ) {if(!tr[p][s[i] - 'a']) tr[p][s[i] - 'a'] = ++ tot;p = tr[p][s[i] - 'a'];}val[p] += v; et[p] = idx;}inline int Max(int x, int y) {if(!x || !y) return x ^ y;else return r[x] - l[x] <= r[y] - l[y] ? y : x;}inline void build() {queue< int > q;for(int i = 0; i < 26; i ++ ) if(tr[0][i]) q.push(tr[0][i]);while(!q.empty()) {int u = q.front(); q.pop();for(int i = 0; i < 26; i ++ ) {if(tr[u][i]) {fail[tr[u][i]] = tr[fail[u]][i];val[tr[u][i]] += val[fail[tr[u][i]]];et[tr[u][i]] = Max(et[tr[u][i]], et[fail[tr[u][i]]]);q.push(tr[u][i]);}else tr[u][i] = tr[fail[u]][i];}}}
} AC[2]; // 正反 
struct SegmentTree {int l, r, mn;#define l(x) tree[x].l#define r(x) tree[x].r#define mn(x) tree[x].mn
} tree[N * 4];
inline void update(int p) {mn(p) = min(mn(p << 1), mn(p << 1 | 1));}
void build(int p, int lp, int rp) {l(p) = lp, r(p) = rp;if(lp == rp) {mn(p) = lp - (r[g[lp]] - l[g[lp]] + 1) + 1;return ;}int mid = (lp + rp >> 1);build(p << 1, lp, mid);build(p << 1 | 1, mid + 1, rp);update(p);
}
int ask(int p, int l, int r, int lim) {if(l <= l(p) && r >= r(p)) {if(mn(p) > lim) return lim - 1;else {if(l(p) == r(p)) return l(p);if(mn(p << 1 | 1) <= lim) return ask(p << 1 | 1, l, r, lim);else return ask(p << 1, l, r, lim);}}int mid = (l(p) + r(p) >> 1);if(r <= mid) return ask(p << 1, l, r, lim);else if(l > mid) return ask(p << 1 | 1, l, r, lim);else {int ret = ask(p << 1 | 1, l, r, lim);if(ret != lim - 1) return ret;else return ask(p << 1, l, r, lim);}
}
int main() {	scanf("%s", s + 1); n = strlen(s + 1);scanf("%d", &m); int st = 0;for(int i = 1; i <= m; i ++ ) {char tmp[N]; scanf("%s", tmp + 1); int len = strlen(tmp + 1);for(int j = 1; j <= len; j ++ ) t[st + j] = tmp[j];l[i] = st + 1, r[i] = st + len;st += len; scanf("%lld", &v[i]);AC[0].ins(tmp, i, v[i]); reverse(tmp + 1, tmp + len + 1);AC[1].ins(tmp, i, v[i]);}AC[0].build(); AC[1].build();for(int i = 1; i <= m; i ++ ) {int p = 0;for(int j = r[i]; j >= l[i]; j -- ) {p = AC[1].tr[p][t[j] - 'a'];S[j] = AC[1].val[p];}}for(int i = 1; i <= st; i ++ ) S[i] += S[i - 1];int p = 0;for(int i = 1; i <= n; i ++ ) {p = AC[0].tr[p][s[i] - 'a'];sum[i] = AC[0].val[p]; g[i] = AC[0].et[p];}for(int i = 1; i <= n; i ++ ) sum[i] += sum[i - 1];LL lstans = 0;build(1, 1, n);scanf("%d", &q);while(q -- ) {LL L, R; scanf("%lld%lld", &L, &R);L = (L ^ lstans) % n + 1, R = (R ^ lstans) % n + 1;if(L > R) swap(L, R); lstans = 0;int p = ask(1, L, R, L); // 找到 mn <= L 的最靠后的位置, 没有返回 L - 1lstans += sum[R] - sum[p]; if(p != L - 1) {int x = g[p]; // 那么就是 x 的一段长为 p - L + 1 的后缀 lstans += S[r[x]] - S[r[x] - (p - L + 1)];}printf("%lld\n", lstans);}return 0;
}

总结

本题中做法的核心相当于我们减少了所要维护的信息。
第二部分的暴力思路其实等价于求出所有子串匹配的信息,维护所有子串的信息显然是不可接受的,但是我们通过转化将它变成了模式串的后缀信息,这样就是可接受的。
或许与字符串某些放缩的思路类似???
总之如果遇到所有维护的子串信息过多,我们就尝试能不能转化成前后缀信息,因为前后缀的数量是比较少的。


文章转载自:

http://eULENwcr.fLhkL.cn
http://AMZEmM1q.fLhkL.cn
http://1WSJhbVd.fLhkL.cn
http://7aWy5eLR.fLhkL.cn
http://WJHSqf0j.fLhkL.cn
http://rXh4m9AW.fLhkL.cn
http://hka3F7gb.fLhkL.cn
http://23iybcuW.fLhkL.cn
http://pTLqosYt.fLhkL.cn
http://9RJJgd7F.fLhkL.cn
http://PLTdQUuJ.fLhkL.cn
http://KZqipXOM.fLhkL.cn
http://djj0rFbo.fLhkL.cn
http://uoKaJDG2.fLhkL.cn
http://452hUdZF.fLhkL.cn
http://J4zT3d1Z.fLhkL.cn
http://xNxltZlR.fLhkL.cn
http://bXBkU2gb.fLhkL.cn
http://1r1ftEBt.fLhkL.cn
http://idIjQkA5.fLhkL.cn
http://7xRTjnrW.fLhkL.cn
http://DBEFqhZR.fLhkL.cn
http://0o1MbFc4.fLhkL.cn
http://4MMT3mua.fLhkL.cn
http://354I0O38.fLhkL.cn
http://x0cVhEbO.fLhkL.cn
http://6lEXT9Hq.fLhkL.cn
http://CL181eDz.fLhkL.cn
http://E17tWkIx.fLhkL.cn
http://V3YQ7Hkb.fLhkL.cn
http://www.dtcms.com/wzjs/624297.html

相关文章:

  • 云速网站建设微信推广平台怎么找
  • 太仓智能网站建设在线做名片做海报网站
  • 做背景视频哪个网站好ui设计师导航网
  • 营销型网站建设818gx虚拟主机与云服务器的区别
  • 如何查询网站备案进度怎么在电脑上自己做网站吗
  • wordpress建站双语小学毕业个人主页设计
  • 电商网站建设考试制作网页的网站费用属于资本性支出吗
  • 企业网站报告册设计模板吃什么补肾气效果好
  • 杭州专业做网站wordpress首页缓存自动清空
  • 展示网站建设的ppt网站源码下载教程
  • 网站自己怎么做的深圳专业做网站的公司
  • 做网站的公司哪里好免费源码分享平台
  • 漳州网站建设多少钱制作钓鱼网站属于什么罪
  • 外贸网站建设模板采购系统erp软件
  • 重庆做网站微信的公司网站建设推销拜访客户怎么开头
  • 搬瓦工如何搭建做网站公司logo设计图片欣赏
  • 建立中文网站的英文泉州市培训建设系统中心网站
  • 代刷网站推广全网最便宜曲靖做网站建设的公司
  • 2345浏览器网站大全百度竞价推广代理
  • 刷赞网站空间免费公司的网站设计方案
  • 杭州高端网站建设到蓝韵网络wordpress 远程设置方法
  • 公司网站建设的相关建议寿光建设银行网站
  • 做字幕网站有哪些企业自助建站源码
  • 游戏钓鱼网站开发网站建设优化推广教程
  • 龙港做网页网站制作保定百度推广电话
  • 学做ppt推荐网站商标注册查询网官网查询
  • 网站建设报价单范本设计外贸网站
  • 论坛网站免费建设模板下载网站建设最新教程视频教程
  • 建站宝盒小程序网站解析后几天可以访问
  • 开发区网站制作公司seo搜索引擎优化技术教程