NOIopenjudge 407:Heritage

总时间限制: 
5000ms
 
内存限制: 
65536kB
描述
Your rich uncle died recently, and the heritage needs to be divided among your relatives and the church (your uncle insisted in his will that the church must get something). There are N relatives (N <= 18) that were mentioned in the will. They are sorted in descending order according to their importance (the first one is the most important). Since you are the computer scientist in the family, your relatives asked you to help them. They need help, because there are some blanks in the will left to be filled. Here is how the will looks: 

Relative #1 will get 1 / ... of the whole heritage, 
Relative #2 will get 1 / ... of the whole heritage,
---------------------- ...
Relative #n will get 1 / ... of the whole heritage.

The logical desire of the relatives is to fill the blanks in such way that the uncle's will is preserved (i.e the fractions are non-ascending and the church gets something) and the amount of heritage left for the church is minimized.
输入
The only line of input contains the single integer N (1 <= N <= 18).
输出
Output the numbers that the blanks need to be filled (on separate lines), so that the heritage left for the church is minimized.
样例输入
2
样例输出
2
3
来源
ural 1108
贪心的来想如果只有一个人那就是1/2 , 两个个人就是1/2,1/3 ,还剩下1/6,如果还要分给下一个人,就会1/7 ,还剩1/42,同理下一个人得1/43,然后看出规律了吧,
然后我们就涉及到了高精乘,然而普通高精乘是过不了的,所以可以用fft,或者ntt这种黑科技(奇技淫巧)。
以下是我ntt
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std ;
  5 typedef long long LL ;
  6 const int  P = ( 479 << 21 ) + 1 , N = 1 << 18 , G = 3 , NUM = 23 ;
  7 int m , len , l1 , l2 ; 
  8 LL a[N] , b[N] , wn[NUM] ; 
  9 
 10 void Init( )
 11 {
 12     scanf( "%d" , &m ) ;
 13     if( m > 2 ) l1 = 1 , l2 = 1 , a[0] = 2 , b[0] = 3 , len = 4 ;   
 14 } 
 15 
 16 LL quick_mod( LL a , LL b , LL m )
 17 {
 18     LL ans = 1ll ;
 19     a %= m ;
 20     while( b )  
 21     {
 22         if( b & 1 ) ans = ans * a % m ;
 23         b >>= 1 ;
 24         a = a * a % m ;
 25     }
 26     return ans ; 
 27 } 
 28 
 29 void Rader( LL a[] , int n )
 30 {
 31     int j = n >> 1 ;
 32     for( int i = 1 ; i < n - 1 ; ++i )
 33     {
 34         if( i < j ) swap( a[i] , a[j] ) ;
 35         int k = n >> 1 ;
 36         while( j >=k )
 37         {
 38             j -= k ;
 39             k >>= 1 ;
 40         }
 41         if( j < k ) j += k ;
 42     }    
 43 
 44 }
 45 
 46 void NTT( LL a[] , int n , int on )
 47 {
 48     Rader( a , n ) ;
 49     int id = 0 ;     
 50     for( int h = 2 ; h <= n ; h <<= 1 )
 51     {
 52         ++id ;
 53         for( int j = 0 ; j < n ; j += h )
 54         {
 55             LL w = 1 ;
 56             for( int k = j ; k < j + ( h >> 1 ) ; ++k ) 
 57             {
 58                 LL u = a[k] % P ;
 59                 LL t = w * a[k+(h>>1)] % P ;
 60                 a[k] = ( u + t ) % P ;
 61                 a[k+(h>>1)] = ( u - t + P ) % P ;
 62                 w = w * wn[id] % P ; 
 63             }
 64         }
 65     }
 66     if( on == -1 )
 67     {
 68         for( int i = 1 ; i <  ( n >> 1 ) ; ++i ) swap( a[i] , a[n-i] ) ;
 69         LL inv = quick_mod( n , P - 2 , P ) ;
 70         for( int i = 0 ; i < n ; ++i  ) a[i] = a[i] * inv % P ; 
 71     }
 72 
 73 }
 74 
 75 
 76 void Conv( LL a[] , LL b[] , int n )
 77 {
 78     NTT( a , n , 1 ) ;
 79     NTT( b , n , 1 ) ;
 80     for( int i = 0 ; i < n ; ++i )
 81         a[i] = a[i] * b[i] % P ; 
 82     NTT( a , n , -1 ) ;
 83 }
 84 
 85 void Transfer( LL a[] , int n )
 86 {
 87     for( int i = 0 ; i < n ; ++i )
 88     {
 89         a[i+1] += a[i]/10 ;
 90         a[i] %= 10 ;
 91         if( a[i] ) l1 = i ;  
 92     } ++l1 ;
 93 }
 94 
 95 void Update( LL b[] , int n )
 96 {
 97     int t = 1 ; l2 = n ; 
 98     for( int i = 0 ; i <= n ; ++i )
 99     {
100         b[i] = a[i] + t ;
101         t = b[i]/10 ; b[i] %= 10 ;
102     }
103     if( b[l1] ) ++l2 ; 
104     
105 }
106 
107 void print( LL b[] , int n )
108 {
109     for( int i = l2 - 1 ; i >= 0 ; --i ) putchar( b[i] + '0' ) ;
110     puts( "" ) ;
111 }
112 
113 void Length( int l1 , int l2 )
114 {
115     while( len <= (l1<<1) || len <= (l2<<1) ) len <<= 1 ;
116 }
117 
118 void Getwn( )
119 {
120     for( int i = 0 ; i < NUM ; ++i ) wn[i] = quick_mod( G , (P-1)/(1<<i) , P ) ;
121 }
122 
123 void Solve( )
124 {
125     if( m >= 1 ) puts( "2" ) ;
126     if( m >= 2 ) puts( "3" ) ;
127     if( m <= 2 ) return ;
128     Getwn( ) ;
129     for( int i = 3 ; i <= m ; ++i )
130     {
131         for( int i = l2 ; i <= len ; ++i ) b[i] = 0 ; 
132         Conv( a , b , len ) ; 
133         Transfer( a , len ) ;
134         Update( b , l1 ) ;
135         print( b , l2 ) ; 
136         Length( l1 , l2 ) ; 
137     }
138         
139 }
140 
141 int main( )
142 {
143     Init( ) ;
144     Solve( ) ;
145     return 0 ;
146 }
原文地址:https://www.cnblogs.com/Ateisti/p/6014036.html