this problem from acm.timus.ruを解決しようとしていましたが、基本的に与えられた文字列(最大長5000)の異なる部分文字列の数を出力したいと思っていました。std :: setはstd :: mapよりどのように遅く設定されていますか?
私が提示しようとしている解決策は、制約が与えられた場合、時間制限超過判定のためには必然的に非効率的で運命的です。しかし、これらの2つのソリューションが異なる(少なくとも私が見る/理解できる限り)唯一の方法は、を使用し、もう1つはstd::set <long long>
を使用するということです(最後のforループの最初を参照してください。任意の差分ツールで確認できます)。マップソリューションは「テスト3で時間制限を超過する」結果となりますが、設定ソリューションでは「テスト2で時間制限が超過する」という結果になります。つまり、テスト2ではマップソリューションが設定ソリューションより速く動作します。これは、Microsoft Visual Studio 2010コンパイラを選択した場合です。私がGCCを選択すると、両方のソリューションがテスト3のTLEになります。
問題を効率的に解決する方法はありません。私は をどのように尋ねているのですか?std::map
を使用すると、明らかにstd::set
を使用するより効率的であると説明できます。私はこの現象の仕組みを見て、誰かが洞察力を持つことができればと思っています。
CODE1(マップ、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;
}
自分で時間を測定するようなことを試しましたか?またはプロファイリング? – PlasmaHH
@PlasmaHH:私は、ある人が他の人よりも遅いという十分な証拠を私は信じています。私はそれが可能である方法に興味があります –
@PlasmaHH:これは完全に適切な質問であると私は信じています。 –