题目链接:http://codeforces.com/problemset/problem/599/D
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 15 squares 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 is 15 + 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,找出所有的 M*N 矩阵,使得其中恰含 X 个正方形
思路:自己推导可以发现,对于任意一个n*m的矩阵,正方形个数为 n*m个边长为1的,(n-1)(m-1)个边长为2的....
也就是
得到这个公式我们还是没法求啊 ,因为K的范围是1e18,我们不可能枚举所有的n和m吧,那么我们看看这个公式
稍作分析,其实我们可以化简得到
到这就好求啦,我们只要枚举n,假设所有的n<=m就行了,直接算出m的值,这样复杂度就降下来了
看代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<stack> #include<map> using namespace std; typedef long long LL; #define sc1(a) scanf("%lld",&a); #define pf1(a) printf("%lld ",a) const int INF=1e9+7; const int maxn=1e6+5; const int maxv=1e6+5; const int mod=998244353; /** m=(6x−n+n^3)/(3n^2+3n) */ vector<pair<LL,LL> >v; int main() { // freopen("in.txt","r",stdin); LL X;sc1(X); ///假设所有的n<=m for(LL i=1;;i++) { LL n=i; LL m=((LL)6*X-n+(LL)n*n*n)/((LL)3*n*n+3*n); if(n>m) break; if(m*((LL)3*n*n+(LL)3*n)==((LL)6*X-n+(LL)n*n*n)) { v.push_back(make_pair(n,m)); } } ///特判两个相等的情况!!! 这个要记得 反过来输出一定要特判两个数相等的情况 LL sum=v.size()<<1; if(v.back().first==v.back().second) sum--; pf1(sum); for(int i=0;i<v.size();i++) { printf("%lld %lld ",v[i].first,v[i].second); } if(v.back().first==v.back().second) v.pop_back(); for(int i=v.size()-1;i>=0;i--) { printf("%lld %lld ",v[i].second,v[i].first); } return 0; } /** */