题目描述:
给定字符串 S 和 T, 定义两个字符串匹配当且仅当每种字符的数量相等, 求 S 的哪些连续子串与 T 匹配.
字符集大小,字符串S,T长度小于等于100w;

这个题面不大完整,他要求的匹配是指对应位置的在各自字符串中都是同一种数;
例如 3 1 3 和2 4 2,3和2对应,1和4对应,所以匹配;
3 3 1和2 4 2虽然数目相等,但位置不匹配;

这题被讲题dalao一笔带过。。。考试的时候几乎要想到整解,不过当时脑子还是没转过来那个弯。。。

考虑记一个w数组,w[i]表示字符i与上一个和他相同的字符在字符串中的距离,如果没有则记为0;
我一开始是想求和后一个字符的距离,但这样无法线性更改。。。只能用个堆+tle…

这样T的w[i]可以很容易的表示出来;

但有个问题,在S中w数组是随着匹配位置变化的;
这题一般有两种做法,一种是用kmp匹配,一种是哈希,这里我只会哈希。。。
那么就考虑随着匹配位置的移动把S的哈希值给改掉;
这里再记一个next数组,表示这个字符下一次会在哪里出现;
这里就能看出为什么要求与之前的距离,因为这样可以随着移动通过next数组把不符合的值改掉;
详细说,如果当前这个next的值指向匹配范围还要往后,直接将其指向的那个点的w值改为0即可;
如果这个点正好在匹配的范围内,则要连带S的哈希值一起改;
那么这题就完了(赶紧写完回宾馆qwq

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<utility>
#define LL long long
using std::pair;
const int maxn=1000005;
LL pow1[maxn]={1ll},pow2[maxn]={1ll};
struct mod_auto{LL val,di,mod,*pow;void clear(){for(int i=1;i<=maxn-3;i++)pow[i]=pow[i-1]*di%mod; } LL gethash(int *v,int n){LL tv=0;for(int i=1;i<=n;i++)tv=(tv*di+(LL)v[i])%mod;return tv;}LL add(int v){val=(val*di+(LL)v)%mod;}LL modify(int pos,int v){val=(val-(LL)v*pow[pos-1]%mod+mod)%mod;}
}mod1;
int t,c;
int v1[maxn],v2[maxn];
int use[maxn];
int next[maxn];
int read(){int tv=0;char c=getchar();while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9'){tv=tv*10+c-'0';c=getchar(); }return tv;
}
pair<int,int> init(){int n,m;scanf("%d%d",&n,&m);memset(use,0,sizeof(use));for(int i=1;i<=n;i++)v1[i]=read();for(int i=1;i<=m;i++)v2[i]=read();for(int i=1;i<=m;i++){int tv=v2[i];v2[i]=(use[v2[i]] ? i-use[v2[i]] : 0),use[tv]=i;}memset(use,0,sizeof(use));for(int i=n;i;i--)next[i]=use[v1[i]],use[v1[i]]=i;memset(use,0,sizeof(use));for(int i=1;i<=n;i++){int tv=v1[i]; v1[i]=use[v1[i]] ? i-use[v1[i]] : 0,use[tv]=i;}return std::make_pair(n,m);
}
int ans[maxn];
void solve(pair<int,int> num){int n=num.first,m=num.second;LL mo=mod1.gethash(v2,m);int anstot=0;mod1.val=mod1.gethash(v1,m);for(int i=1;i<=n-m+1;i++){if(mod1.val==mo)ans[++anstot]=i;if(next[i]){if(next[i]<i+m)mod1.modify(m-(next[i]-i),v1[next[i]]); v1[next[i]]=0;}mod1.add(v1[i+m]);}printf("%d\n",anstot);for(int i=1;i<=anstot;i++)printf("%d ",ans[i]);printf("\n");
}
int main()
{freopen("xiz.in","r",stdin);freopen("xiz.out","w",stdout);mod1.di=(LL)maxn,mod1.mod=1000000007,mod1.pow=pow1;mod1.clear();scanf("%d%d",&t,&c);while(t--)solve(init());return 0;
}

[雅礼集训]xiz(字符串匹配)相关推荐

  1. 2017国庆 雅礼集训 题解合集

    D1 D1 T1:Clique: 我做的题太少啦,这都没看出来.首先,这个式子是 c[i]−c[j]>=dis(i,j) c[i]-c[j] >= dis(i,j),即在数轴上这样的圆,如 ...

  2. 数据结构二之线段树Ⅱ——KiKi‘s K-Number,ball,The Child and Sequence,「雅礼集训 2017 Day1」市场,Atlantis

    值域线段树+势能线段树+扫描线 KiKi's K-Number ball The Child and Sequence 「雅礼集训 2017 Day1」市场 Atlantis KiKi's K-Num ...

  3. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  4. #6029. 「雅礼集训 2017 Day1」市场(势能,区间除)

    #6029. 「雅礼集训 2017 Day1」市场 用线段树维护数列,区间上维护最大最小值,区间和还有标记,修改时,区间加直接做,而区间除时,递归到线段树上某一区间,如果这一操作等价于区间加(也就是最 ...

  5. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  6. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 -- 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  7. 雅礼集训及WC2018划水记

    雅礼集训1.30~2.3 noip考成250,没得去thuwc和pkuwc,和czy等去参加本来只有samjia和栋栋的集训队模拟.抱着被虐的心态去比赛. 第一天刚到比较困,比赛有点没精神,看到t3的 ...

  8. LibreOJ 6514. 「雅礼集训 2018 Day10」文明【虚树+LCA】

    6514. 「雅礼集训 2018 Day10」文明 [题目描述] 传送门 [题解] 考虑笨蛋的写法,可以用LCA求出1号和其他点的中点,然后DFS搜索Size大小即可,但是,复杂度显然要炸,但是我们会 ...

  9. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  10. 雅礼集训2017day1 矩阵

    雅礼集训2017day1 矩阵 题目大意 给你一个 n × n n\times n n×n的 01 01 01矩阵,每次操作将一行转置后赋值到一列.如果能让矩阵全为 1 1 1,则输出最小操作次数:否 ...

最新文章

  1. Duwamish深入剖析-配置篇
  2. shell mysql e_xshell怎么搭建mysql
  3. Android studio/sdk/appium/jdk遇到的坑坑洼洼
  4. UNIX再学习 -- 网络与网络协议
  5. ios html5 网页取消默认样式
  6. 如何限制SELECT-OPTIONS的选择屏幕的OPTION
  7. hmm 求隐藏序列_结巴分词3--基于汉字成词能力的HMM模型识别未登录词
  8. 关于 SAP Commerce Cloud 启动时报 Address already in use - bind 的错误消息
  9. P2831 [NOIP2016 提高组] 愤怒的小鸟 状压dp
  10. 8月份比亚迪纯电动汽车产销量双双超过3万辆 是去年同期3倍多
  11. java 线程安全性_i++是线程安全的吗?如何解决线程安全性?
  12. 《Python机器学习——预测分析核心算法》——2.4 基于因素变量的实数值预测:鲍鱼的年龄...
  13. linux部署tomcat8(基于centOS7)
  14. unity3d android 后台运行,unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android...
  15. 模拟登录,发送amf类型数据
  16. 寻找两个有序数组最小相同元素---JavaScript--解决方法
  17. 交点处批量性一次打断lisp_cad批量交点打断.VLX
  18. 操作系统 进程调度实验报告
  19. 杀毒软件工作原理 及 现在主要杀毒技术
  20. 软件工程复习笔记——项目计划

热门文章

  1. It seems that scikit-learn has not been built correctly
  2. c语言课程设计作业医院挂号系统,c语言课程设计机房机位预定系统绝对正确,附源代码...
  3. git 一个分支完全覆盖另一个分支
  4. 不良资产证券化未来推进需跨越的障碍
  5. 弹孔,血迹 等受击表现
  6. 使用HBuilder打包App教程(图文教程)
  7. 对于最小二乘法的解释
  8. 平凡之路_2022年
  9. Hi,你有一封来自 Googlers 的邀约
  10. oracle数据库开发认证,数据库考试简介之Oracle认证