zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    后向边
    图的割点、桥和双连通分支的基本概念
    Hihocoder 1062 最近公共祖先1
    会场问题 差分解法
    POJ2976 01分数规划 普通题
    Hihocoder 1049
    hihocoder 1050树中最长路
    Hihocoder 1055
    POJ1463
    C语言|博课作业02
  • 原文地址:https://www.cnblogs.com/Ateisti/p/6014036.html
Copyright © 2011-2022 走看看