题解 谜之阶乘
发现答案可以被表示成 \(a\) 的下降幂
于是特判下降次数为1
开根check下降次数为2和3
剩下的可以开根check,怕掉精度的话也可以开map预处理
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
#define ld long double
#define fir first
#define sec second
#define make make_pair
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF: *p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
ll n;
namespace force{
int top;
pair<int, int> sta[N];
void solve() {
int T=read();
while (T--) {
n=read(); top=0;
if (n==1) {puts("-1"); continue;}
for (int i=2; i<n; ++i) {
for (int j=1; j<i; ++j) {
ll tem=1;
for (int k=0; k<j; ++k) tem*=1ll*(i-k);
if (tem==n) sta[++top]=make(i, i-j);
}
}
sta[++top]=make(n, n-1);
sort(sta+1, sta+top+1);
printf("%lld\n", top);
for (int i=1; i<=top; ++i) printf("%lld %lld\n", sta[i].fir, sta[i].sec);
}
exit(0);
}
}
namespace task1{
int top, cnt;
pair<int, int> sta[N];
struct hash_map{
static const int SIZE=1000010;
int head[SIZE], size;
struct node{int next, prod; pair<int, int> dat;}e[SIZE<<1];
hash_map() {memset(head, -1, sizeof(head)); size=0;}
void insert(int n, pair<int, int> val) {
// cout<<"cnt: "<<++cnt<<endl;
int t=n%SIZE;
e[++size].dat=val; e[size].prod=n; e[size].next=head[t]; head[t]=size;
}
void query(int n) {
int t=n%SIZE;
for (int i=head[t]; ~i; i=e[i].next)
if (e[i].prod==n) sta[++top]=e[i].dat;
}
}mp;
void solve() {
int T=read();
for (int i=4; i<=100; ++i) {
for (int j=pow(1e18, 1.0/i); j>1; --j) {
// cout<<"i: "<<i<<endl;
// cout<<"j: "<<j<<endl;
__int128 tem=1;
for (int k=0; k<i; ++k) {
tem*=(j+k);
if (tem>1e18) break;
}
// cout<<"tem: "<<tem<<endl;
if (tem<=1e18) mp.insert(tem, make(j+i-1, j-1));
}
}
while (T--) {
n=read(); top=0;
if (n==1) {puts("-1"); continue;}
if (n>2) {
ll t=sqrt((ld)n);
if (t*(t+1)==n) sta[++top]=make(t+1, t-1);
}
if (n>6) {
ll t=pow((ld)n, 1.0/3.0);
if (t*(t+1)*(t+2)==n) sta[++top]=make(t+2, t-1);
}
mp.query(n);
sta[++top]=make(n, n-1);
sort(sta+1, sta+top+1);
printf("%lld\n", top);
for (int i=1; i<=top; ++i) printf("%lld %lld\n", sta[i].fir, sta[i].sec);
}
exit(0);
}
}
signed main()
{
freopen("factorial.in", "r", stdin);
freopen("factorial.out", "w", stdout);
// force::solve();
task1::solve();
return 0;
}