我试图从 acm.timus.ru 解决这个问题,它基本上希望我输出给定字符串的不同子字符串的数量(最大长度 5000)。
我即将提出的解决方案效率极低,并且由于限制因素而注定要做出超出时间限制的判决。但是,这两种解决方案的唯一区别(至少据我所见/理解)是一种使用std::map<long long, bool>
,而另一种使用std::set <long long>
(参见最后一个 for 循环的开头。其余部分相同,您可以检查通过任何差异工具)。地图解决方案导致“测试 3 超过时间限制”,而设置解决方案导致“测试 2 超过时间限制”,这意味着测试 2 使得地图解决方案在其上的工作速度比设置解决方案更快。如果我选择 Microsoft Visual Studio 2010 编译器,就会出现这种情况。如果我选择 GCC,那么这两种解决方案都会导致测试 3 中的 TLE。
我不是在问如何有效地解决问题。我要问的是如何解释 usingstd::map
显然比 using 更有效std::set
。我只是看不到这种现象的机制,希望有人能有任何见解。
代码 1(使用地图,TLE 3):
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
int main ()
{
string s;
cin >> s;
vector <long long> p;
p.push_back(1);
for (int i = 1; i < s.size(); i++)
p.push_back(31 * p[i - 1]);
vector <long long> hash_temp;
hash_temp.push_back((s[0] - 'a' + 1) * p[0]);
for (int i = 1; i < s.size(); i++)
hash_temp.push_back((s[i] - 'a' + 1) * p[i] + hash_temp[i - 1]);
int n = s.size();
int answer = 0;
for (int i = 1; i <= n; i++)
{
map <long long, bool> hash_ans;
for (int j = 0; j < n - i + 1; j++)
{
if (j == 0)
hash_ans[hash_temp[j + i - 1] * p[n - j - 1]] = true;
else
hash_ans[(hash_temp[j + i - 1] - hash_temp[j - 1]) * p[n - j - 1]] = true;
}
answer += hash_ans.size();
}
cout << answer;
}
Code2(使用集合,TLE 2):
#include <iostream>
#include <string>
#include <vector>
#include <set>
using namespace std;
int main ()
{
string s;
cin >> s;
vector <long long> p;
p.push_back(1);
for (int i = 1; i < s.size(); i++)
p.push_back(31 * p[i - 1]);
vector <long long> hash_temp;
hash_temp.push_back((s[0] - 'a' + 1) * p[0]);
for (int i = 1; i < s.size(); i++)
hash_temp.push_back((s[i] - 'a' + 1) * p[i] + hash_temp[i - 1]);
int n = s.size();
int answer = 0;
for (int i = 1; i <= n; i++)
{
set <long long> hash_ans;
for (int j = 0; j < n - i + 1; j++)
{
if (j == 0)
hash_ans.insert(hash_temp[j + i - 1] * p[n - j - 1]);
else
hash_ans.insert((hash_temp[j + i - 1] - hash_temp[j - 1]) * p[n - j - 1]);
}
answer += hash_ans.size();
}
cout << answer;
}