Tôi đã cố gắng giải quyết this problem from acm.timus.ru mà về cơ bản muốn tôi xuất số lượng các đoạn khác nhau của một chuỗi đã cho (độ dài tối đa 5000).Làm thế nào là std :: thiết lập chậm hơn std :: bản đồ?
Các giải pháp mà tôi sắp trình bày tuyệt đối không hiệu quả và phải chịu số phận hạn chế thời gian vượt quá giới hạn cho các ràng buộc. Tuy nhiên, cách duy nhất trong đó hai giải pháp này khác nhau (ít nhất là tôi có thể thấy/hiểu) là sử dụng std::map<long long, bool>
, còn cách khác sử dụng std::set <long long>
(xem phần đầu của vòng lặp cuối cùng. có thể kiểm tra bằng bất kỳ công cụ tìm khác biệt nào). Giải pháp bản đồ kết quả trong "Giới hạn thời gian vượt quá thử nghiệm 3", trong khi giải pháp thiết lập kết quả trong "Giới hạn thời gian vượt quá thử nghiệm 2", có nghĩa là Phép thử 2 là giải pháp bản đồ hoạt động nhanh hơn so với giải pháp đã đặt. Đây là trường hợp nếu tôi chọn trình biên dịch Microsoft Visual Studio 2010. Nếu tôi chọn GCC, thì cả hai giải pháp dẫn đến TLE khi thử nghiệm 3.
Tôi không yêu cầu cách giải quyết vấn đề hiệu quả. Những gì tôi yêu cầu là làm thế nào người ta có thể giải thích rằng việc sử dụng std::map
rõ ràng có thể hiệu quả hơn việc sử dụng std::set
. Tôi chỉ không nhìn thấy cơ chế của hiện tượng này và hy vọng rằng ai đó có thể có bất kỳ thông tin chi tiết nào.
Code1 (sử dụng bản đồ, 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 (sử dụng bộ, 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;
}
Bạn đã thử một cái gì đó cho bản thân, chẳng hạn như tự mình đo thời gian? hoặc thậm chí là hồ sơ? – PlasmaHH
@PlasmaHH: Tôi tin rằng tôi đã đưa ra bằng chứng đầy đủ rằng bằng chứng đó là chậm hơn so với cái kia. Tôi quan tâm đến cách đó có thể là –
@PlasmaHH: Tôi tin rằng đây là một câu hỏi hoàn toàn phù hợp. –