【省内训练2018-11-25】Factorization

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/84564043

【思路要点】

  • 用类似 Min25Min25 的过程进行搜索即可。
  • 具体来说,先用线性筛得出 N\sqrt{N} 以内的质数,记 primeiprime_i 表示第 ii 个质数。
  • 定义过程 work(x,y,z)work(x,y,z) 表示处理大于等于 primeyprime_y 的质因子乘积不超过 xx ,小于 primeyprime_y 的质因子的指数信息为 zz 的数对答案的贡献。
  • 我们需要处理的即为 work(N,1,)work(N,1,\empty)
  • 对于 work(x,y,z)work(x,y,z) ,我们将大于等于 primeyprime_y 的质因子乘积为质数的数单独处理,显然,这些数是属于一类的,其个数即为 [primey,x][prime_y,x] 中质数的个数,可以事先筛出。
  • 否则,枚举下一个质因数 primeiprime_i ,满足 primei2x,primeiprimeyprime_i^2≤x,prime_i≥prime_y ,并枚举其指数 ee ,满足 primeie+1xprime_i^{e+1}≤x ,调用 work(xprimeie,i,z+e)work(\lfloor\frac{x}{prime_i^e}\rfloor,i,z+e) 即可。
  • 时间复杂度 O(NPoly(LogN)α)O(\frac{N}{Poly(LogN)}*\alpha) ,其中 α\alpha 为统计答案带来的复杂度因子。

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 5;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
ll n, val[MAXN], cnt[MAXN];
int limit, m, home1[MAXN], home2[MAXN];
map <vector <int>, ll> ans;
int tot, prime[MAXN], f[MAXN];
void getans(ll x, int y, vector <int> now) {
	now.push_back(1);
	sort(now.begin(), now.end(), [&] (int x, int y) {return x > y; });
	ll delta = -(y - 1);
	if (x <= limit) delta += cnt[home1[x]];
	else delta += cnt[home2[n / x]];
	if (delta > 0) ans[now] += delta;
}
void sieve() {
	for (ll i = 1, nxt; i <= n; i = nxt + 1) {
		ll tmp = n / i;
		val[++m] = tmp;
		cnt[m] = tmp - 1;
		if (tmp <= limit) home1[tmp] = m;
		else home2[n / tmp] = m;
		nxt = n / tmp;
	}
	for (int i = 1; i <= tot; i++) {
		for (int j = 1; 1ll * prime[i] * prime[i] <= val[j]; j++) {
			ll tmp = val[j] / prime[i]; int pos = 0;
			if (tmp <= limit) pos = home1[tmp];
			else pos = home2[n / tmp];
			cnt[j] -= cnt[pos] - (i - 1);
		}
	}
}
void work(ll x, int y, vector <int> now) {
	getans(x, y, now);
	if (x < prime[y] || y > tot) return;
	for (int i = y; i <= tot && 1ll * prime[i] * prime[i] <= x; i++) {
		ll val = prime[i], tmp = 1ll * prime[i] * prime[i];
		for (int j = 1; tmp <= x; j++, val = tmp, tmp *= prime[i]) {
			vector <int> tnow = now;
			tnow.push_back(j + 1);
			sort(tnow.begin(), tnow.end(), [&] (int x, int y) {return x > y; });
			ans[tnow]++;
			now.push_back(j);
			work(x / val, i + 1, now);
			now.pop_back();
		}
	}
}
void init(int n) {
	for (int i = 2; i <= n; i++) {
		if (f[i] == 0) prime[++tot] = f[i] = i;
		for (int j = 1; j <= tot && prime[j] <= f[i]; j++) {
			int tmp = prime[j] * i;
			if (tmp > n) break;
			f[tmp] = prime[j];
		}
	}
}
int main() {
	read(n);
	limit = sqrt(n) + 1;
	init(limit + 100);
	sieve();
	vector <int> tmp;
	tmp.clear();
	work(n, 1, tmp);
	printf(": 1\n");
	for (auto x : ans) {
		static int cnt[36];
		ll ans = x.second;
		memset(cnt, 0, sizeof(cnt));
		for (auto y : x.first) {
			printf("%d ", y);
			ans *= ++cnt[y];
		}
		printf(": %lld\n", ans);
	}
	return 0;
}
阅读更多

Factorization

08-27

Problem DescriptionnLMY and YY are mathematics lovers. They like to find and solve interesting mathematic problems together. One day, they found that the polynomial “x^n-1” can be factorized into a large number of long polynomials, although the polynomial “x^n-1” looks simple. They were interested in how to factorize it into irreducible polynomials.nnBy “irreducible” we mean that it has co-prime coefficients and cannot be further factorized.nnNow your task is to help LMY and YY to factorize x^n-1 into several irreducible polynomials over the integers.n nnInputnThe input consists of multiple test cases.nFor each test case, there is one line containing only one integer N. (2<=N<=1001)nnEnd of input is indicated by a line containing a zero.n nnOutputnFor each test case, output the factorization of the given polynomial according to the writing habit, i.e. x^5, 5x^2, 3x, x^2-x.nnThere are multiple ways to express the factorization of a polynomial. To make it unique, we sort the irreducible polynomials according to the following rules:nnLower order polynomials are always lexicographically smaller than higher order polynomials. Same order polynomials should be sorted by their coefficients. We compare the coefficients from high degree terms to low degree terms, including the omitted terms, which the coefficients are regard as 0. Coefficients are being compared first by absolute value then by sign. Smaller absolute values are lexicographically smaller. For the same absolute value, negative coefficients are lexicographically smaller than positive coefficients.n nnSample Inputn2n3n4n5n6n12n256n0n nnSample Outputn(x-1)(x+1)n(x-1)(x^2+x+1)n(x-1)(x+1)(x^2+1)n(x-1)(x^4+x^3+x^2+x+1)n(x-1)(x+1)(x^2-x+1)(x^2+x+1)n(x-1)(x+1)(x^2+1)(x^2-x+1)(x^2+x+1)(x^4-x^2+1)n(x-1)(x+1)(x^2+1)(x^4+1)(x^8+1)(x^16+1)(x^32+1)(x^64+1)(x^128+1)

没有更多推荐了,返回首页