Tire。
思路很蠢,每个串的最后一个结点记录该串出现次数。然后在树上dfs求相同结点数*串个数的最大值。
第一次用scanf超时,后来改成gets,优化了一下读入,1.8s水过。。。
后来发现了,下面两份代码都是,时间主要花费在memset上面了,由于数组太大,memset花费时间太长,每次开始的时候没必要memset,而是建树的时候清空就可以了。
改了之后速度快了很多。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define INF 200000000
#define MOD 20071027
#define MAXN 5005
using namespace std;
int sz;
int ch[10000005][3],val[10000005];
void Init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
val[0]=1;
}
int idx(char c)
{
return c-'0';
}
void Insert(char *word)
{
int u=0;
for(int i=0; word[i]; ++i)
{
int x=idx(word[i]);
if(ch[u][x]==0)
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][x]=sz++;
}
u=ch[u][x];
}
val[u]++;
}
int ans=0;
int solve(int u,int cur)
{
if(!u) return 0;
int cnt=solve(ch[u][0],cur+1)+solve(ch[u][1],cur+1)+val[u];
ans=max(cur*cnt,ans);
return cnt;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Init();
int n;
scanf("%d",&n);
char word[205];
getchar();
for(int i=0; i<n; ++i)
{
gets(word);
Insert(word);
}
ans=0;
solve(ch[0][0],1);
solve(ch[0][1],1);
printf("%d\n",ans);
}
return 0;
}
网上看到的思路,对于每个结点保存它的长度和出现次数。这样只需要遍历所有结点,取长度*次数的最大值即可。
相比我的思路,这个思路在建树的时候就保留了有用的信息。而我的还需要遍历到树的叶子结点才行。
总感觉我的思路也是O(n)的。。
但是这个代码速度也很慢。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define INF 200000000
#define MOD 20071027
#define MAXN 5005
using namespace std;
int sz;
int ch[10000005][3],val[10000005],len[10000005];
void Init()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
val[0]=1;
}
int idx(char c)
{
return c-'0';
}
void Insert(char *word)
{
int u=0;
for(int i=0; word[i]; ++i)
{
int x=idx(word[i]);
if(ch[u][x]==0)
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][x]=sz++;
}
u=ch[u][x];
len[u]=i+1;
val[u]++;
}
}
int ans=0;
int buf[10];
inline void writeint(int i)
{
int p=0;
if(i==0) p++;
else while(i)
{
buf[p++]=i%10;
i/=10;
}
for(int j=p-1; j>=0; --j) putchar(buf[j]+'0');
putchar('\n');
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Init();
int n;
scanf("%d",&n);
char word[205];
getchar();
for(int i=0; i<n; ++i)
{
gets(word);
//scanf("%s",word);
Insert(word);
}
ans=0;
for(int i=1; i<sz; ++i)
ans=max(ans,len[i]*val[i]);
printf("%d\n",ans);
//writeint(ans);
}
return 0;
}