Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class HashCode {
- public:
- struct X {
- int server;
- int latency;
- };
- struct EndPoint{
- int latencyDefault;
- vector<X> latencies;
- };
- struct Request {
- int video;
- int endpoint;
- int id;
- int64_t count;
- };
- void solve(std::ifstream& in, std::ofstream& out) {
- cerr << fixed;
- cerr.precision(20);
- int n_videos, n_endpoints, n_requests, n_servers, capacity;
- in >> n_videos >> n_endpoints >> n_requests >> n_servers >> capacity;
- vector<int> videos(n_videos);
- for (int& i: videos) {
- in >> i;
- }
- vector<EndPoint> endpoints(n_endpoints);
- for (int i: range(n_endpoints)) {
- in >> endpoints[i].latencyDefault;
- int k;
- in >> k;
- endpoints[i].latencies.resize(k);
- for (int j: range(k)) {
- in >> endpoints[i].latencies[j].server >> endpoints[i].latencies[j].latency;
- }
- }
- vector<Request> requests(n_requests);
- for (int i: range(n_requests)) {
- in >> requests[i].video >> requests[i].endpoint >> requests[i].count;
- requests[i].id = i;
- }
- auto best_latency = [&](const Request& request, const vector<set<int>>& answer) {
- int endpoint = request.endpoint;
- int best = endpoints[endpoint].latencyDefault;
- for (const auto& x: endpoints[endpoint].latencies) {
- if (answer[x.server].count(request.video)) {
- best = min(best, x.latency);
- }
- }
- return best;
- };
- auto score = [&](const vector<set<int>>& answer) {
- int64_t optimized = 0;
- int64_t all_requests = 0;
- for (auto& request: requests) {
- int endpoint = request.endpoint;
- int best = best_latency(request, answer);
- optimized += (endpoints[endpoint].latencyDefault - best) * request.count;
- all_requests += request.count;
- }
- return optimized * 1000.0 / all_requests;
- };
- auto print_ans = [&](const vector<set<int>>& answer) {
- out << answer.size() << "\n";
- for (int i: range((int)answer.size())) {
- out << i;
- for (int ans: answer[i]) {
- out << ' ' << ans;
- }
- out << "\n";
- }
- };
- assert(videos[0] <= capacity);
- vector<vector<int>> video2requests(n_videos);
- for (auto& request: requests) {
- video2requests[request.video].push_back(request.id);
- }
- vector<int> current_capacity(n_servers, capacity);
- vector<set<int>> server2videos(n_servers);
- vector<int> bestLatency(n_requests);
- for (int i: range(n_requests)) {
- bestLatency[i] = endpoints[requests[i].endpoint].latencyDefault;
- }
- vector<int> server_count(n_servers);
- for (auto& request: requests) {
- int endpoint = request.endpoint;
- for (auto x: endpoints[endpoint].latencies) {
- server_count[x.server] += 2;
- }
- }
- auto calc = [&](int64_t improvement, int video_size, int server) {
- return pow(improvement, 1.) / 1.0 / pow(video_size, 1.01) / pow(min(improvement + 1, (int64_t)server_count[server]), 0.38);
- };
- for (int _: range(1)) {
- //set<pair<int64_t, pair<int, int>>, greater<pair<int64_t, pair<int, int>>>> scores_sorted;
- auto scores = make_vector<double>(n_videos, n_servers, 0);
- {
- for (auto& request: requests) {
- int endpoint = request.endpoint;
- for (auto x: endpoints[endpoint].latencies) {
- if (current_capacity[x.server] < videos[request.video]) {
- continue;
- }
- int64_t improvement = max(0, bestLatency[request.id] - x.latency) * request.count;
- scores[request.video][x.server] += calc(improvement, videos[request.video], x.server);
- }
- }
- }
- auto lambda = [&](auto& p, auto& q) {
- if (p == q) {
- return false;
- }
- return scores[p.first][p.second] > scores[q.first][q.second] || scores[p.first][p.second] == scores[q.first][q.second] && p < q;
- };
- multiset<pair<int, int>, decltype(lambda)> scores_sorted(lambda);
- {
- for (int i: range(n_videos)) {
- for (int j: range(n_servers)) {
- //scores_sorted.insert(make_pair(scores[i][j], make_pair(i, j)));
- scores_sorted.emplace(i, j);
- }
- }
- }
- while (!scores_sorted.empty()) {
- auto seitem = *scores_sorted.begin();
- scores_sorted.erase(scores_sorted.begin());
- auto video = seitem.first;
- auto server = seitem.second;
- if (current_capacity[server] < videos[video]) {
- continue;
- }
- for (int j: range(n_servers)) {
- int i = video;
- //scores_sorted.erase(make_pair(scores[i][j], make_pair(i, j)));
- scores_sorted.erase(make_pair(i, j));
- scores[video][j] = 0;
- }
- current_capacity[server] -= videos[video];
- server2videos[server].insert(video);
- for (auto& request: video2requests[video]) {
- assert(requests[request].video == video);
- bestLatency[request] = best_latency(requests[request], server2videos);
- for (auto& x: endpoints[requests[request].endpoint].latencies) {
- int64_t improvement = max(0, bestLatency[request] - x.latency) * requests[request].count;
- scores[video][x.server] += calc(improvement, videos[requests[request].video], x.server);
- }
- }
- for (int j: range(n_servers)) {
- int i = video;
- if (scores[video][j] > 0 && current_capacity[j] >= videos[video]) {
- //scores_sorted.insert(make_pair(scores[i][j], make_pair(i, j)));
- scores_sorted.emplace(i, j);
- }
- }
- }
- }
- cerr << score(server2videos) << endl;
- print_ans(server2videos);
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement