现在每天做的题都记录一下,免得不知道自己在干什么。
POJ2406:用Next数组的定义求循环节
POJ3261:后缀数组论文题
SPOJ705:同上,这题我Wa了几次,结果发现:我以为字符串只有大写字母,其实有小写。
代码如下:
POJ2406
/*
* @Author: duyixian
* @Date: 2015-11-14 14:27:16
* @Last Modified by: duyixian
* @Last Modified time: 2015-11-14 14:39:42
*/
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using namespace std;
#define MAX_SIZE 1000005
#define INF 0x3F3F3F3F
#define Eps
#define Mod
inline int Get_Int()
{
int Num = 0, Flag = 1;
char ch;
do
{
ch = getchar();
if(ch == '-')
Flag *= -1;
}
while(ch < '0' || ch > '9');
do
{
Num = Num * 10 + ch - '0';
ch = getchar();
}
while(ch >= '0' && ch <= '9');
return Num * Flag;
}
int Length;
int Next[MAX_SIZE];
char Str[MAX_SIZE];
int main()
{
while(scanf("%s", Str + 1) != EOF)
{
if(Str[1] == '.')
break;
Length = strlen(Str + 1);
memset(Next, 0, sizeof(Next));
for(int i = 2, k = 0; i <= Length; ++i)
{
while(k && Str[k + 1] != Str[i])
k = Next[k];
if(Str[k + 1] == Str[i])
Next[i] = ++k;
}
if(Length % (Length - Next[Length]))
printf("1\n");
else
printf("%d\n", Length / (Length - Next[Length]));
}
return 0;
}
POJ3261:
/*
* @Author: duyixian
* @Date: 2015-11-14 14:51:22
* @Last Modified by: duyixian
* @Last Modified time: 2015-11-14 15:15:12
*/
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using namespace std;
#define MAX_SIZE 20005
#define INF 0x3F3F3F3F
#define Eps
#define Mod
inline int Get_Int()
{
int Num = 0, Flag = 1;
char ch;
do
{
ch = getchar();
if(ch == '-')
Flag *= -1;
}
while(ch < '0' || ch > '9');
do
{
Num = Num * 10 + ch - '0';
ch = getchar();
}
while(ch >= '0' && ch <= '9');
return Num * Flag;
}
int N, Limit = 20000, K;
int Num[MAX_SIZE], SA[MAX_SIZE], SA1[MAX_SIZE], Rank[MAX_SIZE], Rank1[MAX_SIZE], Height[MAX_SIZE], Bucket[MAX_SIZE];
inline void Calculate_SA()
{
for(int i = 1; i <= N; ++i)
++Bucket[Rank[i] = Num[i]];
for(int i = 1; i <= Limit; ++i)
Bucket[i] += Bucket[i - 1];
for(int i = N; i; --i)
SA[Bucket[Rank[i]]--] = i;
for(int j = 1, k = 0; k < N; j <<= 1, Limit = k)
{
k = 0;
for(int i = N - j + 1; i <= N; ++i)
SA1[++k] = i;
for(int i = 1; i <= N; ++i)
if(SA[i] > j)
SA1[++k] = SA[i] - j;
swap(Rank, Rank1);
for(int i = 1; i <= N; ++i)
Rank[i] = Rank1[SA1[i]];
for(int i = 0; i <= Limit; ++i)
Bucket[i] = 0;
for(int i = 1; i <= N; ++i)
++Bucket[Rank[i]];
for(int i = 1; i <= Limit; ++i)
Bucket[i] += Bucket[i - 1];
for(int i = N; i; --i)
SA[Bucket[Rank[i]]--] = SA1[i];
k = 0;
for(int i = 1; i <= N; ++i)
k = max(k, Rank[SA[i]] = Rank[SA[i - 1]] + (Rank1[SA[i]] != Rank1[SA[i - 1]] || Rank1[SA[i] + j] != Rank1[SA[i - 1] + j]));
}
}
inline void Calculate_Height()
{
int k = 0;
for(int i = 1; i < N; ++i)
{
int j = SA[Rank[i] - 1];
while(Num[j + k] == Num[i + k])
++k;
Height[Rank[i]] = k;
if(k)
--k;
}
}
inline bool Find(int Length)
{
for(int i = 2; i <= N;)
{
while(i <= N && Height[i] < Length)
++i;
int Num = 1;
while(i <= N && Height[i] >= Length)
{
++Num;
++i;
}
if(Num >= K)
return true;
}
return false;
}
inline void Solve()
{
int Left = 0, Right = N + 1, Mid = Left + Right + 1 >> 1;
while(Mid != Left && Mid != Right)
{
if(Find(Mid))
Left = Mid;
else
Right = Mid;
Mid = Left + Right + 1 >> 1;
}
cout << Left << endl;
}
int main()
{
cin >> N >> K;
for(int i = 1; i <= N; ++i)
Num[i] = Get_Int();
++N;
Calculate_SA();
Calculate_Height();
Solve();
return 0;
}
SPOJ705:
/*
* @Author: duyixian
* @Date: 2015-11-14 15:58:21
* @Last Modified by: duyixian
* @Last Modified time: 2015-11-14 16:47:07
*/
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using namespace std;
#define MAX_SIZE 50005
#define INF 0x3F3F3F3F
#define Eps
#define Mod
inline int Get_Int()
{
int Num = 0, Flag = 1;
char ch;
do
{
ch = getchar();
if(ch == '-')
Flag *= -1;
}
while(ch < '0' || ch > '9');
do
{
Num = Num * 10 + ch - '0';
ch = getchar();
}
while(ch >= '0' && ch <= '9');
return Num * Flag;
}
int T, N, Limit;
int Rank[MAX_SIZE], SA[MAX_SIZE], Rank1[MAX_SIZE], SA1[MAX_SIZE], Bucket[MAX_SIZE], Height[MAX_SIZE];
long long Ans;
char Str[MAX_SIZE];
inline void Calculate_SA()
{
Limit = 256;
memset(Bucket, 0, sizeof(Bucket));
for(int i = 1; i <= N; ++i)
++Bucket[Rank[i] = Str[i]];
for(int i = 1; i <= Limit; ++i)
Bucket[i] += Bucket[i - 1];
for(int i = N; i; --i)
SA[Bucket[Rank[i]]--] = i;
for(int j = 1, k = 0; k < N; j <<= 1, Limit = k)
{
k = 0;
for(int i = N - j + 1; i <= N; ++i)
SA1[++k] = i;
for(int i = 1; i <= N; ++i)
if(SA[i] > j)
SA1[++k] = SA[i] - j;
swap(Rank1, Rank);
for(int i = 1; i <= N; ++i)
Rank[i] = Rank1[SA1[i]];
for(int i = 0; i <= Limit; ++i)
Bucket[i] = 0;
for(int i = 1; i <= N; ++i)
++Bucket[Rank[i]];
for(int i = 1; i <= Limit; ++i)
Bucket[i] += Bucket[i - 1];
for(int i = N; i; --i)
SA[Bucket[Rank[i]]--] = SA1[i];
k = 0;
for(int i = 1; i <= N; ++i)
k = max(k, Rank[SA[i]] = Rank[SA[i - 1]] + (Rank1[SA[i - 1]] != Rank1[SA[i]] || Rank1[SA[i - 1] + j] != Rank1[SA[i] + j]));
}
}
inline void Calculate_Height()
{
int k = 0;
for(int i = 1; i < N; ++i)
{
int j = SA[Rank[i] - 1];
while(Str[j + k] == Str[i + k])
++k;
Height[Rank[i]] = k;
if(k)
--k;
}
}
int main()
{
cin >> T;
while(T--)
{
Ans = 0;
scanf("%s", Str + 1);
N = strlen(Str + 1);
++N;
Calculate_SA();
Calculate_Height();
for(int i = 2; i <= N; ++i)
Ans += (long long)(N - SA[i] - Height[i]);
cout << Ans << endl;
}
return 0;
}