結果

問題 No.886 Direct
ユーザー hasegawa1
提出日時 2021-08-24 00:27:54
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
RE  
実行時間 -
コード長 5,175 bytes
コンパイル時間 911 ms
コンパイル使用メモリ 85,536 KB
実行使用メモリ 54,400 KB
最終ジャッジ日時 2024-11-08 09:10:14
合計ジャッジ時間 30,333 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample RE * 4
other RE * 32
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In member function 'std::vector<long int> Sieve::divisors(int64_t) const':
main.cpp:68:24: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   68 |         for(const auto [p, exp]: prime_factorize(n)) {
      |                        ^
main.cpp: In member function 'int64_t Sieve::euler_phi(int64_t) const':
main.cpp:86:24: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17' [-Wc++17-extensions]
   86 |         for(const auto [p, exp]: prime_factorize(n)) {
      |                        ^

ソースコード

diff #
プレゼンテーションモードにする

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cstdint>
#include <cassert>
#include <atcoder/modint>
using namespace std;
using mint = atcoder::modint1000000007;
class Sieve {
private:
const int _n;
std::vector<int> _max_prime_factor;
std::vector<int> _euler_phi;
public:
explicit Sieve(int n = 2'000'000): _n(n+1), _max_prime_factor(_n), _euler_phi(_n) {
iota(_euler_phi.begin(), _euler_phi.end(), 0);
for(int i=2; i<_n; i++) {
if(_max_prime_factor[i]) continue;
for(int j=i; j<_n; j+=i) {
_max_prime_factor[j] = i;
_euler_phi[j] -= _euler_phi[j]/i;
}
}
}
bool is_prime(int64_t n) const {
assert(n > 0);
if(n < _n) return (_max_prime_factor[n] == n);
return atcoder::internal::is_prime_constexpr(n);
}
std::vector<std::pair<int64_t,int64_t>> prime_factorize(int64_t n) const {
assert(n > 0);
std::vector<std::pair<int64_t,int64_t>> res;
if(n < _n) {
while(n > 1) {
int64_t p = _max_prime_factor[n];
int64_t exp = 0;
while(_max_prime_factor[n] == p) {
n /= p;
++exp;
}
res.emplace_back(p, exp);
}
std::reverse(res.begin(), res.end());
} else {
for(int64_t i=2; i*i<=n; i++) {
if(n%i == 0) {
int exp = 0;
while(n%i == 0) {
n /= i;
++exp;
}
res.emplace_back(i, exp);
}
}
if(n != 1) res.emplace_back(n, 1);
}
return res;
}
std::vector<int64_t> divisors(int64_t n) const {
assert(n > 0);
std::vector<int64_t> res = {1};
for(const auto [p, exp]: prime_factorize(n)) {
int sz = res.size();
for(int i=0; i<sz; i++) {
int64_t now = res[i];
for(int j=0; j<exp; j++) {
now *= p;
res.emplace_back(now);
}
}
}
sort(res.begin(), res.end());
return res;
}
int64_t euler_phi(int64_t n) const {
assert(n > 0);
if(n < _n) return _euler_phi[n];
int64_t res = n;
for(const auto [p, exp]: prime_factorize(n)) {
res -= res/p;
}
return res;
}
template<typename T>
std::vector<T> divisor_transform(std::vector<T> v) {
assert(v.size() <= _n);
for(int i=2; i<_n; i++) {
if(is_prime(i)) {
for(int j=1; i*j<_n; j++) {
v[j * i] += v[j];
}
}
}
return v;
}
template<typename T>
std::vector<T> inverse_divisor_transform(std::vector<T> v) {
assert(v.size() <= _n);
for(int i=2; i<_n; i++) {
if(is_prime(i)) {
for(int j=(_n-1)/i; i>0; j--) {
v[j * i] -= v[j];
}
}
}
return v;
}
template<typename T>
std::vector<T> multiple_transform(std::vector<T> v) {
assert(v.size() <= _n);
for(int i=2; i<_n; i++) {
if(is_prime(i)) {
for(int j=(_n-1)/i; i>0; j--) {
v[j] += v[j * i];
}
}
}
return v;
}
template<typename T>
std::vector<T> inverse_multiple_transform(std::vector<T> v) {
assert(v.size() <= _n);
for(int i=2; i<_n; i++) {
if(is_prime(i)) {
for(int j=1; i*j<_n; j++) {
v[j] -= v[j * i];
}
}
}
return v;
}
template<typename T>
std::vector<T> gcd_convolution(const std::vector<T> &a, const std::vector<T> &b) {
assert(a.size() == b.size());
auto sum_a = multiple_transform(a);
auto sum_b = multiple_transform(b);
std::vector<T> sum_c;
std::transform(sum_a.begin(), sum_a.end(), sum_b.begin(), std::back_inserter(sum_c), std::multiplies<T>());
return inverse_multiple_transform(sum_c);
}
template<typename T>
std::vector<T> lcm_convolution(const std::vector<T> &a, const std::vector<T> &b) {
assert(a.size() == b.size());
auto sum_a = divisor_transform(a);
auto sum_b = divisor_transform(b);
std::vector<T> sum_c;
std::transform(sum_a.begin(), sum_a.end(), sum_b.begin(), std::back_inserter(sum_c), std::multiplies<T>());
return inverse_divisor_transform(sum_c);
}
};
int main(void) {
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
Sieve s;
int H, W;
cin >> H >> W;
int M = max(H, W);
vector<mint> h(M+1), w(M+1);
for(int i=1; i<H; i++) {
h[i] = H-i;
}
for(int i=1; i<W; i++) {
w[i] = W-i;
}
mint ans = (H-1)*W + H*(W-1) + s.gcd_convolution(h, w)[1];
cout << ans.val() << endl;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0