P3861 8月月赛A
https://www.luogu.org/problemnew/show/P3861
排序:乘数保持单调递增
dp+hash(map解决)
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define E 2.7182818284 23 const ll mod=1e9+7;//998244353 24 const int maxn=1e6+10; 25 26 bool vis[maxn]; 27 ll zhi[maxn],x[maxn],y[maxn],s[maxn],tot[8000]; 28 ll n,nn; 29 int g=0,g1=0,g2=0,g3=0; 30 map<int,int>st; 31 32 void getzhi() 33 { 34 int i,j,value=1e6; 35 for (i=2;i<=value;i++) 36 { 37 if (!vis[i]) 38 { 39 g++; 40 zhi[g]=i; 41 } 42 for (j=1;j<=g;j++) 43 { 44 if (i*zhi[j]>value) 45 break; 46 vis[i*zhi[j]]=1; 47 if (i%zhi[j]==0) 48 break; 49 } 50 } 51 } 52 53 void getzys(int index,ll value) 54 { 55 ll v=1; 56 int i; 57 for (i=0;i<=y[index];i++) 58 { 59 if (index!=g1) 60 getzys(index+1,value*v); 61 else 62 { 63 g2++; 64 s[g2]=value*v; 65 } 66 v=v*x[index]; 67 } 68 } 69 70 void getr(int index,ll value) 71 { 72 if (value==1) 73 { 74 g3++; 75 return; 76 } 77 if (index==g2+1 || value<s[index]) 78 return; 79 for (int i=index;i<=g2;i++) 80 if (value%s[i]==0) 81 getr(i+1,value/s[i]); 82 } 83 84 void work() 85 { 86 int i,j; 87 // g2=-1; //ignore zys 1 88 g2=0; 89 getzys(1,1); 90 // g2--; //ignore zys n 91 sort(s+1,s+g2+1); 92 93 st.clear(); 94 for (i=1;i<=g2;i++) 95 st[s[i]]=i; 96 97 //from big to small ,ignore repetition 98 memset(tot,0,sizeof(tot)); 99 tot[1]=1; 100 for (i=2;i<g2;i++) //ascending 101 for (j=g2;j>=i;j--) // *s[i]=s[j] 102 if (s[j]%s[i]==0) 103 tot[j]+=tot[st[s[j]/s[i]]]; 104 printf("%lld\n",tot[g2]); //- (n*1) 105 106 ///超时 107 // g3=0; 108 // getr(1,nn); 109 // printf("%d\n",g3); 110 } 111 112 int main() 113 { 114 int t,i; 115 getzhi(); 116 scanf("%d",&t); 117 while (t--) 118 { 119 scanf("%lld",&n); 120 nn=n; 121 g1=0; 122 for (i=1;i<=g;i++) 123 if (n%zhi[i]==0) 124 { 125 g1++; 126 x[g1]=zhi[i]; 127 y[g1]=0; 128 while (n%zhi[i]==0) 129 { 130 y[g1]++; 131 n/=zhi[i]; 132 } 133 if (n==1) 134 break; 135 } 136 if (n!=1) 137 { 138 g1++; 139 x[g1]=n; 140 y[g2]=1; 141 } 142 work(); 143 } 144 return 0; 145 }