Я реализовал две версии решения для следующей задачи LeetCode: максимальные и минимальные суммы при последующих размерах k < br/>
Учитывая целочисленные массивы nums и положительное целое число k , верните сумму максимальных и минимальных элементов всех последствий Nums с максимума k элементы. Поскольку результат может быть большим, вернуть It Modulo 10^9 + 7 .
Обе реализации используют предварительно вычисленные факториалы и модульные образы для эффективного вычисления комбинаций. Однако один инициализирует эти значения в конструкторе класса , в то время как другой использует статическую инициализацию в функции лямбда. Удивительная разница в производительности на LeetCode
code 1 (инициализация на основе конструктора) занимает ~ 2000 мс.
код 2 (статическая инициализация) занимает только ~ 30 мс (~ 66x ускорение). < /li> код 1: инициализация на основе конструктора (~ 2000 мс) < /strong> < /h3>
class Solution {
private:
const int mod = 1e9 + 7;
const int MX = 1e5 + 1;
vector F, REC_F;
public:
Solution() {
F.resize(MX);
REC_F.resize(MX);
F[0] = 1;
for (int i = 1; i < MX; ++i) {
F[i] = F[i - 1] * i % mod;
}
REC_F[MX - 1] = power(F[MX - 1], mod - 2);
for (int i = MX - 2; i >= 0; --i) {
REC_F[i] = REC_F[i + 1] * (i + 1) % mod;
}
}
int minMaxSums(vector& nums, int k) {
sort(nums.begin(), nums.end());
int n = nums.size();
long long ans = 0, s = 1;
for (int i = 0; i < n; ++i) {
ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod;
s = (2 * s - comb(i, k - 1) + mod) % mod;
}
return ans;
}
long long comb(int n, int m) {
return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod;
}
long long power(long long x, int n) {
long long ans = 1;
for (; n > 0; n /= 2) {
if (n % 2) ans = (ans * x) % mod;
x = (x * x) % mod;
}
return ans;
}
};
const int mod = 1'000'000'007;
const int MX = 100'000;
long long F[MX]; // Factorial
long long REC_F[MX]; // Inverse Factorial
long long power(long long x, int n) {
long long ans = 1;
for (; n > 0; n /= 2) {
if (n & 1) ans = (ans * x) % mod;
x = (x * x) % mod;
}
return ans;
}
auto init = [] {
F[0] = 1;
for (int i = 1; i < MX; ++i) {
F[i] = F[i - 1] * i % mod;
}
REC_F[MX - 1] = power(F[MX - 1], mod - 2);
for (int i = MX - 2; i >= 0; --i) {
REC_F[i] = REC_F[i + 1] * (i + 1) % mod;
}
return 0;
}();
class Solution {
public:
int minMaxSums(vector& nums, int k) {
sort(nums.begin(), nums.end());
int n = nums.size();
long long ans = 0, s = 1;
for (int i = 0; i < n; ++i) {
ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod;
s = (2 * s - comb(i, k - 1) + mod) % mod;
}
return ans;
}
long long comb(int n, int m) {
return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod;
}
};
< /code>
< /li>
< /ul>
[b] наблюдения и вопросы < /strong> < /h3>
code 1 (инициализация на основе конструктора) значительно более медленнее (~ 2000 мс). < /strong> < /p>
< /li >
code 2 (статическая инициализация) ~ 66x быстрее (~ 30 мс). < /strong> < /p>
< /li>
< /ul>
Тем не менее, на моей локальной машине (против компилятора), оба работают примерно через 30 секунд < /strong> с данными тестирования: < /p>
vector nums(1e5, 1e9);
int k = 70;
Почему Leetcode показывает огромную разницу, но локально время выполнения схожи? H3>
Я хотел бы понять, почему такое радикальная разница [/b] происходит между leetcode против моей локальной машины :
создает ли LeetCode несколько экземпляров < /code> на тестовый пример? < /strong> < /p>
< li> Если это так, это объяснило бы, почему инициализация на основе конструктора намного медленнее. < /li>
< /ul>
< /li>
Есть ли какая -то модель оптимизации или выполнения компилятора, которая вызывает такое поведение? < /Strong> < /p>
Понизирует ли компилятор LeetCode статическую инициализацию? < /Li>
может ли кеширование или повторное использование памяти повлиять на производительность на LeetCode?
< ul>
Статические переменные сохраняются по тестовым случаям. Может ли это повысить эффективность на LeetCode? < /Li>
< /ul>
< /li>
< /ol>
оценил бы любую информацию о Как различные модели выполнения Stravic Stime выполнения в C ++.
Я реализовал две версии решения для следующей задачи LeetCode: 🔗 [b] максимальные и минимальные суммы при последующих размерах k [/b] < br/> Учитывая целочисленные массивы nums и положительное целое число k , верните сумму максимальных и минимальных элементов всех последствий Nums с максимума k элементы. Поскольку результат может быть большим, вернуть It Modulo 10^9 + 7 .
Обе реализации используют [b] предварительно вычисленные факториалы и модульные образы [/b] для эффективного вычисления комбинаций. Однако один инициализирует эти значения в конструкторе класса [b] [/b], в то время как другой использует [b] статическую инициализацию [/b] в функции лямбда. 💡 [b] Удивительная разница в производительности на LeetCode [/b] [list] [*] [b] code 1 (инициализация на основе конструктора) занимает ~ 2000 мс. [/b]
[*] [b] код 2 (статическая инициализация) занимает только ~ 30 мс (~ 66x ускорение). [/b] < /li> [b] код 1: инициализация на основе конструктора (~ 2000 мс) < /strong> < /h3> [code]class Solution { private: const int mod = 1e9 + 7; const int MX = 1e5 + 1; vector F, REC_F;
public: Solution() { F.resize(MX); REC_F.resize(MX); F[0] = 1; for (int i = 1; i < MX; ++i) { F[i] = F[i - 1] * i % mod; } REC_F[MX - 1] = power(F[MX - 1], mod - 2); for (int i = MX - 2; i >= 0; --i) { REC_F[i] = REC_F[i + 1] * (i + 1) % mod; } }
int minMaxSums(vector& nums, int k) { sort(nums.begin(), nums.end()); int n = nums.size(); long long ans = 0, s = 1;
for (int i = 0; i < n; ++i) { ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod; s = (2 * s - comb(i, k - 1) + mod) % mod; } return ans; }
long long comb(int n, int m) { return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod; }
long long power(long long x, int n) { long long ans = 1; for (; n > 0; n /= 2) { if (n % 2) ans = (ans * x) % mod; x = (x * x) % mod; } return ans; } };
[/code] код 2: статическая инициализация (~ 30 мс, ~ 66x быстрее) [/b] [code]const int mod = 1'000'000'007; const int MX = 100'000; long long F[MX]; // Factorial long long REC_F[MX]; // Inverse Factorial
long long power(long long x, int n) { long long ans = 1; for (; n > 0; n /= 2) { if (n & 1) ans = (ans * x) % mod; x = (x * x) % mod; } return ans; }
auto init = [] { F[0] = 1; for (int i = 1; i < MX; ++i) { F[i] = F[i - 1] * i % mod; } REC_F[MX - 1] = power(F[MX - 1], mod - 2); for (int i = MX - 2; i >= 0; --i) { REC_F[i] = REC_F[i + 1] * (i + 1) % mod; } return 0; }();
class Solution { public: int minMaxSums(vector& nums, int k) { sort(nums.begin(), nums.end()); int n = nums.size(); long long ans = 0, s = 1;
for (int i = 0; i < n; ++i) { ans = (ans + s * (nums[i] + nums[n - 1 - i])) % mod; s = (2 * s - comb(i, k - 1) + mod) % mod; } return ans; }
long long comb(int n, int m) { return n < m ? 0 : F[n] * REC_F[m] % mod * REC_F[n - m] % mod; } };
< /code> < /li> < /ul>
[b] наблюдения и вопросы < /strong> < /h3> code 1 (инициализация на основе конструктора) значительно более медленнее (~ 2000 мс). < /strong> < /p> < /li > code 2 (статическая инициализация) ~ 66x быстрее (~ 30 мс). < /strong> < /p> < /li> < /ul> Тем не менее, на моей локальной машине (против компилятора), оба работают примерно через 30 секунд < /strong> с данными тестирования: < /p> vector nums(1e5, 1e9); int k = 70; [/code] Почему Leetcode показывает огромную разницу, но локально время выполнения схожи? H3> Я хотел бы понять, почему такое радикальная разница [/b] происходит между [b] leetcode против моей локальной машины [/b]:
[b] создает ли LeetCode несколько экземпляров < /code> на тестовый пример? < /strong> < /p>
< li> Если это так, это объяснило бы, почему инициализация на основе конструктора намного медленнее. < /li> < /ul> < /li> Есть ли какая -то модель оптимизации или выполнения компилятора, которая вызывает такое поведение? < /Strong> < /p>
Понизирует ли компилятор LeetCode статическую инициализацию? < /Li> [/list]
может ли кеширование или повторное использование памяти повлиять на производительность на LeetCode? [/b] < ul> Статические переменные сохраняются по тестовым случаям. Может ли это повысить эффективность на LeetCode? < /Li> < /ul> < /li> < /ol> оценил бы любую информацию о [b] Как различные модели выполнения [/b] Stravic Stime выполнения в C ++. 🚀
Я реализовал две версии решения для следующей задачи LeetCode:
🔗 максимальные и минимальные суммы при последующих размерах k
Учитывая целочисленные массивы nums и положительное целое число k , верните сумму максимальных и минимальных элементов...
Я реализовал две версии решения для следующей задачи LeetCode:
🔗 максимальные и минимальные суммы при последующих размерах k
Учитывая целочисленные массивы nums и положительное целое число k , верните сумму максимальных и минимальных элементов...
Поскольку C ++ 11 Инициализация функциональных статических переменных является безопасной. Переменная заблокирована (предположительно мутекс) и инициализируется первым потоком, который входит в функцию. То, как он работает, означает, что, очевидно,...
Для следующего класса только с конструктором перемещения:
class Foo {
public:
Foo(const Foo& foo) = delete;
Foo(Foo&& foo) = default;
Foo() = default;
};
Почему инициализация вектора с помощью списка инициализации, такого как вектор vec{Foo()};,...
Для следующего класса только с конструктором перемещения:
class Foo {
public:
Foo(const Foo& foo) = delete;
Foo(Foo&& foo) = default;
Foo() = default;
};
Почему инициализация вектора с помощью списка инициализации, такого как вектор vec{Foo()};,...