luogu4715 「英语」Z 语言
请大家注意,该题会无故 0 分。
请提交,赛后或者修好后会 Rej。
(OI 赛制(大雾
题目描述 英语是高考里最简单的一科了——至少对于小 F 来说是这样。
这一天,英语老师又在瘠义肥辞地讲着模拟题,而小 F 正玩弄着同学的电子词典。这个电子词典有一个特点,便是无法输入英文以外的字符,比如 naïve 只能为 naive,café 只能为 cafe。
小 F 非常讨厌这种设定。为了凸显这种设定的愚蠢之处,小 F 决定设计出一种字符集超大的语言——Z 语言,哪怕有时额外的字符并没有什么用。
这种语言的特点是:
字符集非常大,甚至可能有 2147483648(2 ^ {31})2147483648(231) 种字符;
每个单词由一系列两两不同的字符组成;
字符既能比较相同和不同,也能比较大小,因此之后我们用数字来表示 Z 语言中稀奇古怪的字符;
两个看起来完全不同的单词也可能是同一个单词,因为:只要两个单词中第 K 大的字符所在的位置相同,那么其实就是本质上相同的单词。例如 {1, 2, 3, 4, 5}{1,2,3,4,5} 与 {2, 3, 23, 233, 23333}{2,3,23,233,23333} 是相同的。(所以你可以用 Z 语言很方便地加密信息!)
现在,小 F 打算将 Z 语言应用到实际中。比如,他点开了一道电脑里的算法题:
给定两个字符串 A, BA,B ,求 BB 作为子串在 AA 中被匹配的次数。
小 F 当然知道这是一个可以用 KMP 解决的基础题。但是,他在用 Z 语言的匹配实现 Z-KMP 的时候遇到了问题,你能帮帮他吗?
为了验证你是不是真的明白小 F 在说什么,小 F 会修改 BB 串很多次来问你。可不准偷懒哦!
你的程序需要支持的操作详见输入输出格式。
输入输出格式 输入格式:
输入第一行两个整数 n, m, q(1 \leq n, m, q \leq 10 ^ 5)n,m,q(1≤n,m,q≤105) ,表示 A, BA,B 串的长度。
第二行 nn 个非负整数,第 ii 个表示 AA 串的第 ii 个字符 A_iAi (0 \leq A_i \leq 2147483647=2 ^ {31} - 1)(0≤Ai≤2147483647=231−1) 。
第三行 mm 个非负整数,第 ii 个表示 BB 串的第 ii 个字符 B_iBi (0 \leq B_i \leq 2147483647=2 ^ {31} - 1)(0≤Bi≤2147483647=231−1) 。
接下来 qq 行,每行两个正整数 x_i, c_ixi,ci (1 \leq c_i \leq 2147483647=2 ^ {31} - 1)(1≤ci≤2147483647=231−1) ,表示将 BB 串 x_ixi 位置上的字符由 B_{x_i}Bxi 改为 c_ici 。
数据保证,任意时刻 AA 和 BB 均是满足前述要求的合法 Z 字符串。
输出格式:
在每次修改完成后,请输出 BB 作为子串在 AA 中被 Z-匹配 的次数。
输入输出样例 输入样例#1: 复制 5 3 2 11 7 5 3 2 3 2 1 2 5 1 6 输出样例#1: 复制 0 3 说明 样例 1 解释 在第一次修改后, {3, 5, 1}{3,5,1} 并不能被任何一个 AA 中的子串匹配上。
在第二次修改后, {6, 5, 1}{6,5,1} 能被 AA 中所有长度为 33 的串匹配上,原因是 A 是单调减的,而 B 也是单调减的,因此 AA 中所有长度为 33 的串与 BB 排名相同的处于相同位置。
子任务 子任务 1(31 \mathrm{pts}) : n, m \leq 100, q \leq 10001(31pts):n,m≤100,q≤1000 ;
子任务 2(41 \mathrm{pts}) : n, m \leq 1000, q \leq 5 \times 10 ^ 42(41pts):n,m≤1000,q≤5×104 ;
子任务 3(78 \mathrm{pts}) : n, m, q \leq 10 ^ 53(78pts):n,m,q≤105 。
在splay上维护每个位置的hash值 hash值的定义为 第几大的值出现在哪里
然后先把a序列所有长度为m的hash值都存在hash表里
然后每次修改b序列的时候 获得一个hash值 然后直接去hash表里询问一下出现次数即可
#include#define ll unsigned long longusing namespace std;inline char gc(){ static char now[1<<16],*S,*T; if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;} return *S++;}inline int read(){ int x=0,f=1;char ch=gc(); while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();} while(isdigit(ch)) x=x*10+ch-'0',ch=gc(); return x*f;}const int N=1e5+10;const int g=11117;const int mod=100003;struct node{ ll s;int next,v;}data[N];ll p[N],hs[N],w[N],S;int size[N],fa[N],c[N][2],h[N],num,b[N],n,m,q,rt,v[N];inline void update(int x){ int l=c[x][0],r=c[x][1]; size[x]=size[l]+size[r]+1; hs[x]=hs[l]+p[size[l]]*w[x]+p[size[l]+1]*hs[r];}inline void rotate(int x,int &tar){ int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1; if (y==tar) tar=x;else c[z][c[z][1]==y]=x; fa[c[x][r]]=y;fa[y]=x;fa[x]=z; c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);}inline void splay(int x,int &tar){ while(x!=tar){ int y=fa[x],z=fa[y]; if (y!=tar){ if (c[y][0]==x^c[z][0]==y) rotate(x,tar);else rotate(y,tar); }rotate(x,tar); }}inline void insert1(int &x,int id,int f){ if (!x) {x=id;fa[x]=f;update(x);splay(x,rt);return;} if (v[id] mm;inline void ins(ll s){ //++mm[s];return; int x=s%mod; for (int i=h[x];i;i=data[i].next){ if (s==data[i].s) {++data[i].v;return;} } data[++num].s=s;data[num].v=1;data[num].next=h[x];h[x]=num;}inline int query(ll s){ //return mm[s]; int x=s%mod; for (int i=h[x];i;i=data[i].next){ if (s==data[i].s) return data[i].v; }return 0;}inline void del(int x){ splay(x,rt); if(!(c[x][0]*c[x][1])){rt=c[x][0]+c[x][1];fa[rt]=0;c[x][0]=c[x][1]=0;return;} int succ=c[x][1],pre=c[x][0]; while(c[pre][1]) pre=c[pre][1]; while(c[succ][0]) succ=c[succ][0]; splay(pre,rt);splay(succ,c[rt][1]);c[succ][0]=0;fa[x]=0;update(succ);update(rt);}int main(){ freopen("4715.in","r",stdin); n=read();m=read();q=read();p[0]=1; for (int i=1;i<=n;++i) v[i]=read(); for (int i=1;i<=n;++i) w[i]=i,p[i]=p[i-1]*g; for (int i=1;i<=m;++i) insert1(rt,i,0),S+=p[i-1],b[i]=read(); for (int i=m;i<=n;++i){ ins(hs[rt]-S*(i-m));if (i==n) break; del(i-m+1);insert1(rt,i+1,0); }rt=0;memset(c,0,sizeof(c));memset(fa,0,sizeof(fa)); for (int i=1;i<=m;++i) v[i]=b[i],insert1(rt,i,0); while(q--){ int x=read(),cc=read();del(x);c[x][0]=c[x][1]=0; v[x]=cc;insert1(rt,x,0); printf("%d\n",query(hs[rt])); } return 0;}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~