题目
题解
–这道题我竟然在考场上想出来了正解(笑cry)
这道题不是什么hash,就是一个Trie,可以在每个节点用一个vector存答案,最后查询就是了
但是,当时我vector用太多了,不仅调试慢,而且可能爆空间
所以来优化一下
发现,对于每个节点其实没必要存下所有答案的位置,他为零的区间长度其实只和
当前位置-上次位置-1有关,所以说我们只需要记录上次出现的位置,并且同时维护最长区间长度
不仅建变快了,查询也变快了
这道题还有个神坑,就是这道题的数据是在Windows下生成的,所以换行符是\r\n,
而评测环境是Linux,换行符就是\n,
所以每次要用两个getchar()读取换行(QAQ就是这个一直卡我)
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=5*1e6+5;
int n,m;
char t,s;
struct hehe{
int ans;
int last;
int a;
int b;
int c;
}tree[MAXN];
int cnt;
int ans[100005];
void add(int x,int y){
int v;
t=getchar();
if(t=='a'){
if(!tree[x].a)
tree[x].a=++cnt;
v=tree[x].a;
tree[v].ans=max(tree[v].ans,y-tree[v].last-1);
tree[v].last=y;
add(v,y);
}
else if(t=='b'){
if(!tree[x].b)
tree[x].b=++cnt;
v=tree[x].b;
tree[v].ans=max(tree[v].ans,y-tree[v].last-1);
tree[v].last=y;
add(v,y);
}
else if(t=='c'){
if(!tree[x].c)
tree[x].c=++cnt;
v=tree[x].c;
tree[v].ans=max(tree[v].ans,y-tree[v].last-1);
tree[v].last=y;
add(v,y);
}
else
return ;
}
int Find(int x){
int v;
s=getchar();
if(s=='a'){
v=tree[x].a;
if(!v)
return n;
return Find(v);
}
else if(s=='b'){
v=tree[x].b;
if(!v)
return n;
return Find(v);
}
else if(s=='c'){
v=tree[x].c;
if(!v)
return n;
return Find(v);
}
else
return max(tree[x].ans,n-tree[x].last);
}
int main(){
freopen("word.in","r",stdin);
freopen("word.out","w",stdout);
cin>>n>>m;
getchar();
getchar();
for(int i=1;i<=n;i++){
add(0,i);
getchar();
}
for(int i=1;i<=m;i++){
ans[i]=Find(0);
while(s=='a'||s=='b'||s=='c')
s=getchar();
getchar();
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}