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 }

 

posted @ 2018-08-27 16:12  congmingyige  阅读(149)  评论(0编辑  收藏  举报