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; }