11/5/2018模拟 Problem C
Posted ubospica
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11/5/2018模拟 Problem C相关的知识,希望对你有一定的参考价值。
题面
题解
我有特殊的哈希技巧
以到下一个相同字符的距离为值哈希, 如果不存在或在串外, 就是 (|T| + 1).
加入一个新字符 (S_i) 时, 同时修改它上一次出现时的值, 由 (|T| + 1) 修改为 (i).
详见代码.
代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
#define rep(i,l,r) for(register int i=(l);i<=(r);++i)
#define repdo(i,l,r) for(register int i=(l);i>=(r);--i)
#define il inline
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
//---------------------------------------
const int nsz=1e6+50,msz=1e5+50,base=1e5+3;
int n,m;
char s[nsz],t[msz];
il int tr(char c){return c-'a'+1;}
int nes[nsz],prs[nsz];
int net[msz],prt[msz];
ull hs=0,ht=0,pb[msz]{1};
void gene(char *s,int *ne,int *pr,int n){
static int bot[30];
rep(i,1,26)bot[i]=n+1;
repdo(i,n,1){
ne[i]=bot[tr(s[i-1])];
bot[tr(s[i-1])]=i;
}
rep(i,1,26)bot[i]=0;
rep(i,1,n){
pr[i]=bot[tr(s[i-1])];
bot[tr(s[i-1])]=i;
}
}
void sol(){
gene(s,nes,prs,n);
gene(t,net,prt,m);
rep(i,1,m){
ht=ht*base+(net[i]==m+1?m+1:net[i]-i);
hs=hs*base+(nes[i]>m?m+1:nes[i]-i);
pb[i]=pb[i-1]*base;
}
if(hs==ht)cout<<1<<'
';
ull tmp;
rep(i,m+1,n){//[i-m+1,i]
tmp=(nes[i-m]>i-1?m+1:nes[i-m]-(i-m));
hs=hs*base-tmp*pb[m];
tmp=i-prs[i];
if(tmp<m){
hs-=(m+1-tmp)*pb[tmp]; //dynamically modify
}
hs+=m+1;
if(hs==ht)cout<<i-m+1<<'
';
}
}
int main(){
// freopen("c.in","r",stdin);
// freopen("c.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0);
cin>>s>>t;
n=strlen(s),m=strlen(t);
if(n<m)return 0;
sol();
return 0;
}
以上是关于11/5/2018模拟 Problem C的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 864C-Bus-(模拟加油站问题)
HDU 1032 [The 3n + 1 problem] 暴力模拟
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段