【CodeForces - 599D】Spongebob and Squares(推公式+枚舉)

題意:

在一張3*5的網格圖中,有15個1*1的矩陣,有8個2*2的矩陣,有3個3*3的矩陣,一共有26個不同的正方形。

現在已知一個矩形中包含一定數量的正方形,問這個矩形有多少種不同的可能。

Input

第一行包含一個整數 x (1 ≤ x ≤ 1018) — 表示矩形中包含的正方形個數。

Output

輸出整數k表示有多少種不同的矩形滿足條件

之後輸出 k 對整數,每對整數描述一個矩形。按照 n 遞增的順序輸出。

Example

Input

26

Output

6
1 26
2 9
3 5
5 3
9 2
26 1

Input

2

思路:

假設行數是k時,總共的格子數是m,我們的目標是找列的長度設爲n(k<=n,因爲k>n的時候其實在之前出現過)。首先只有一個格子的有k*n個,兩個格子的有(k-1)*(n-1)個

三個格子的有(k-2)*(n-2)...把他們展開加和就能得到等式k*k*n-sum(k-1)(k+n)+sum2(k-1)=m,這裏的sum(n)代表前n項的和,sum2(n)代表前n項的平方和。然後一化簡就得到另一個數爲(m-sum2(k-1)+sum(k-1)*k)/(k*k-sum(k-1))。代入k=1e6,m=1e18時測試,發現這時候k和n已經非常接近,所以直接暴力枚舉就可以,然後用上面公式求出結果。

ac代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#define mod (1000000007)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e5+10;
struct node{
	ll l,r;
}ans[2000000];
ll sum(ll x){ return (x+1)*x/2; }
ll sum2(ll x){ return x*(x+1)*(x+x+1)/6; } 
int main(){
	ll m,k,cnt=0;
	scanf("%lld",&m);
	for(ll k=1;;k++){
		ll t1=(m-sum2(k-1)+sum(k-1)*k);
		ll t2=(k*k-sum(k-1));
		ll tmp=t1/t2;
		if(tmp<k) break;
		if(tmp*t2==t1){
			ans[cnt].l=k;ans[cnt++].r=tmp;
		}
	}
	printf("%d\n",cnt*2-(ans[cnt-1].l==ans[cnt-1].r));
	for(int i=0;i<cnt;i++){
		printf("%lld %lld\n",ans[i].l,ans[i].r);
	}
	if(ans[cnt-1].l!=ans[cnt-1].r) printf("%lld %lld\n",ans[cnt-1].r,ans[cnt-1].l);
	for(int i=cnt-2;i>=0;i--)
		printf("%lld %lld\n",ans[i].r,ans[i].l);
	return 0;
}
//k
//k*k*n-sum(k-1)(k+n)+sum2(k-1)=m
//tmp=(m-sum2(k-1)+sum(k-1)*k)/(k*k-sum(k-1))另一個數
//
//k*n (k-1)*(n-1) (k-2)(n-2)
//k*n kn-k-n+1   kn-2k-2n+4
//1 n
//2 2*n+1
//3 4n-4

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章