https://www.luogu.org/problemnew/show/P3861
排序:乘数保持单调递增
dp+hash(map解决)
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <time.h>
#include <string>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <ext/rope>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
#define pi 3.1415926536
#define E 2.7182818284
const ll mod=1e9+;//
const int maxn=1e6+; bool vis[maxn];
ll zhi[maxn],x[maxn],y[maxn],s[maxn],tot[];
ll n,nn;
int g=,g1=,g2=,g3=;
map<int,int>st; void getzhi()
{
int i,j,value=1e6;
for (i=;i<=value;i++)
{
if (!vis[i])
{
g++;
zhi[g]=i;
}
for (j=;j<=g;j++)
{
if (i*zhi[j]>value)
break;
vis[i*zhi[j]]=;
if (i%zhi[j]==)
break;
}
}
} void getzys(int index,ll value)
{
ll v=;
int i;
for (i=;i<=y[index];i++)
{
if (index!=g1)
getzys(index+,value*v);
else
{
g2++;
s[g2]=value*v;
}
v=v*x[index];
}
} void getr(int index,ll value)
{
if (value==)
{
g3++;
return;
}
if (index==g2+ || value<s[index])
return;
for (int i=index;i<=g2;i++)
if (value%s[i]==)
getr(i+,value/s[i]);
} void work()
{
int i,j;
// g2=-1; //ignore zys 1
g2=;
getzys(,);
// g2--; //ignore zys n
sort(s+,s+g2+); st.clear();
for (i=;i<=g2;i++)
st[s[i]]=i; //from big to small ,ignore repetition
memset(tot,,sizeof(tot));
tot[]=;
for (i=;i<g2;i++) //ascending
for (j=g2;j>=i;j--) // *s[i]=s[j]
if (s[j]%s[i]==)
tot[j]+=tot[st[s[j]/s[i]]];
printf("%lld\n",tot[g2]); //- (n*1) ///超时
// g3=0;
// getr(1,nn);
// printf("%d\n",g3);
} int main()
{
int t,i;
getzhi();
scanf("%d",&t);
while (t--)
{
scanf("%lld",&n);
nn=n;
g1=;
for (i=;i<=g;i++)
if (n%zhi[i]==)
{
g1++;
x[g1]=zhi[i];
y[g1]=;
while (n%zhi[i]==)
{
y[g1]++;
n/=zhi[i];
}
if (n==)
break;
}
if (n!=)
{
g1++;
x[g1]=n;
y[g2]=;
}
work();
}
return ;
}