Spongebob is already tired trying to reason his weird actions and calculations, so he simply asked you to find all pairs of n and m, such that there are exactly x distinct squares in the table consisting of n rows and m columns. For example, in a 3 × 5 table there are 15squares with side one, 8 squares with side two and 3 squares with side three. The total number of distinct squares in a 3 × 5 table is15 + 8 + 3 = 26.
The first line of the input contains a single integer x (1 ≤ x ≤ 1018) — the number of squares inside the tables Spongebob is interested in.
First print a single integer k — the number of tables with exactly x distinct squares inside.
Then print k pairs of integers describing the tables. Print the pairs in the order of increasing n, and in case of equality — in the order of increasing m.
26
6 1 26 2 9 3 5 5 3 9 2 26 1
2
2 1 2 2 1
8
4 1 8 2 3 3 2 8 1
In a 1 × 2 table there are 2 1 × 1 squares. So, 2 distinct squares in total.
In a 2 × 3 table there are 6 1 × 1 squares and 2 2 × 2 squares. That is equal to 8 squares in total.
题意:给定一个整数x,问有多少个n*m的矩形可以找到x个正方形,要求输出所有矩形的长和宽。
思路:多出几组会发现公式 x = sigma(0<=k<=n-1)(n-k)*(m-k)。
化简公式x = sigma(0<=k<=n-1)n*m - (n+m)*sigma(0<=k<=n-1)k + sigma(0<=k<=n-1)k*k。
根据公式1^2 + 2^2 + 3^2 + ... + n^2 = n*(n+1)*(2*n+1) / 6
再次化简 x = n*n*m - (n+m)*n*(n-1) / 2 + n*(n-1)*(2*n-1) / 6。
6*x = 6*n*n*m - 3*(n+m)*n*(n-1) + n*(n-1)*(2*n-1)。
我们假设n <= m,会发现n最多不会超过2000000。直接暴力即可。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f
#define eps 1e-4
#define MAXN (100000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
using namespace std;
struct Node{
LL x, y;
};
vector<Node> ans;
LL limit = 1000000*6;
void getans(LL x)
{
for(LL i = 1; i <= limit; i++)
{
LL a = 6*x + i*i*i - i;
LL b = 3*i*i + 3*i;
if(a % b)
continue;
LL m = a / b;
if(i > m)
break;
Node now;
now.x = i;
now.y = m;
ans.push_back(now);
}
}
int main()
{
LL x; Rl(x); getans(x);
int top = ans.size()-1;
if(ans[top].x == ans[top].y)
top = ans.size() * 2 - 1;
else
top = ans.size() * 2;
printf("%d\n", top);
int i;
top = ans.size()-1;
for(i = 0; i <= top; i++)
printf("%lld %lld\n", ans[i].x, ans[i].y);
if(ans[top].x == ans[top].y)
i = top-1;
else
i = top;
for(; i >= 0; i--)
printf("%lld %lld\n", ans[i].y, ans[i].x);
return 0;
}