void bvisit(const Pow &x) { if (is_a<const Integer>(*x.get_exp())) { if (rcp_static_cast<const Integer>(x.get_exp())->is_positive()) { x.get_base()->accept(*this); } else { add_to_gen_set(pow(x.get_base(), minus_one), one); } } else if (is_a<const Rational>(*x.get_exp())) { RCP<const Basic> base = x.get_base(); RCP<const Rational> r = rcp_static_cast<const Rational>(x.get_exp()); if (r->is_negative()) base = pow(base, minus_one); add_to_gen_set(base, divnum(one, r->get_den())); } else { umap_basic_num pow_pairs = _find_gens_poly_pow(x.get_exp(), x.get_base()); for (auto it : pow_pairs) add_to_gen_set(pow(x.get_base(), it.first), it.second); } }
void solve(void) { int i, num; num = 0; for (i = 1;; i++) { if (divnum(trinumber(i))) { printf("%d\n", trinumber(i)); break; } } }
// adds curr to gen_set, or updates already existing gen void add_to_gen_set(const RCP<const Basic> &base, const RCP<const Number> &exp) { auto it = gen_set.find(base); if (it == gen_set.end()) { gen_set[base] = exp; return; } if (is_a<const Rational>(*exp)) { RCP<const Integer> den = down_cast<const Rational &>(*exp).get_den(); if (is_a<const Rational>(*it->second)) gen_set[base] = divnum( one, lcm(*den, *down_cast<const Rational &>(*it->second) .get_den())); else gen_set[base] = divnum(one, den); } }
void bvisit(const Mul &x) { // won't handle cases like 2**((x+1)(x+2)) // needs `expand` to have been called RCP<const Number> mulx = one, divx = one; if (x.coef_->is_negative()) mulx = minus_one; if (is_a<const Rational>(*x.coef_)) divx = down_cast<const Rational &>(*x.coef_).get_den(); auto dict = x.dict_; gen_set[Mul::from_dict(mulx, std::move(dict))] = divnum(one, divx); }
void bvisit(const Add &x) { if (not x.coef_->is_zero()) x.coef_->accept(*this); for (auto it : x.dict_) { RCP<const Number> mulx = one, divx = one; if (it.second->is_negative()) mulx = minus_one; if (is_a<const Rational>(*it.second)) divx = down_cast<const Rational &>(*it.second).get_den(); gen_set[mul(mulx, it.first)] = divnum(one, divx); } }
void solve() { static struct { int s[128], m; } cycles[128]; static int s[1024], v[1024]; int i, j, k, t, ncycles; for (i = 0; i < n; i++) { block[i].cycle = 0; block[i].shape = -1; } for (i = 0; i < n; i++) { if (block[i].cycle) continue; for (j = block[i].a, k = n + 5; k-- > 0 && j != i;) j = block[j].a; if (i != j) continue; for (j = block[i].a;; j = block[j].a) { block[j].cycle = 1; if (j == i) break; } } nrshapes = 1; shapes[0].m = 0; for (i = 0; i < n; i++) getshape(i); memset(result, 0, sizeof(result)); mulfact(n); for (i = 0; i < n; i++) { if (block[i].nsub == 0) continue; for (j = 1, k = 1; j < block[i].nsub; j++) { if (block[i].sub[j - 1] == block[i].sub[j]) { k++; } else { mulfact(-k); k = 1; } } mulfact(-k); } memset(v, 0, sizeof(v)); for (ncycles = 0, i = 0; i < n; i++) { if (v[i] || !block[i].cycle) continue; for (j = block[i].a, k = 0;; j = block[j].a) { v[j] = 1; s[k++] = getshape(j); if (j == i) break; } for (j = 0; j < k; j++) s[k + j] = s[j]; for (t = 0, j = 0; j < k; j++) if (memcmp(s, s + j, k * sizeof(int)) == 0) t++; divnum(t); cycles[ncycles].m = k; memcpy(cycles[ncycles].s, s, 2 * k * sizeof(int)); ncycles++; } memset(v, 0, sizeof(v)); for (i = 0; i < ncycles; i++) { if (v[i]) continue; for (k = 0, j = 0; j < ncycles; j++) { if (v[j]) continue; if (cycles[j].m != cycles[i].m) continue; for (t = 0; t < cycles[i].m; t++) if (memcmp(cycles[i].s, cycles[j].s + t, cycles[i].m * sizeof(int)) == 0) break; if (t >= cycles[i].m) continue; v[j] = 1; k++; } mulfact(-k); } print(); }