[P3885] solution of equation (more detailed)

Topic links: https://www.luogu.org/problem/P1771

Want more disciplined, here https://gmoj.net/senior/#main/show/1344

Difference in the memory space limitations.


 

Description

  Allison ran into a problem, to help you solve. For indeterminate equation a1 + a2 + ...... + ak-1 + ak = g (x), where k> = 2 and k∈N *, x is a positive integer, g (x) = x ^ x mod 1000 (i.e., divided by xx the remainder of 1000), x, k is the given number. All we ask is that the number of positive integer solutions group indeterminate equation. For example, when k = 3, x = 2, respectively (a1, a2, a3) = (2,1,1), (1,2,1), (1,1,2).
 

Input

  Enter the file has one and only one line, two positive integers separated by a space, followed by k, x.

Output

  The output file has one and only one line, the number of positive integer solutions group equations.
 

Sample Input

3 2

Sample Output

3

First, the observation of this question.

  1. This is a math problem. (nonsense
  2. To a large range of x, consider use fast power, and then ask the number of decomposition (hereinafter referred to as n) maximum is 1000.
  3. After removal of the size limit x, identify problems remaining part is a template: Given n, k requirements are divided into parts, Partitioned method. That is, the number of combinations standard.
  4. Consider data range again, points system is about: [6 * S * k / (x ^ 3)] + (6 * S) / (x ^ 2) types, where S = 2 ^ (n-1), x = n + 1. (seems to be where the problem is but short this big on the right), found that use high-precision

End of the observation.

Implementation: Combinatorial Mathematics (recursive), fast power, high finishing.

  Formula: C (k, x ^ x% 1000)

  Recursive should be relatively easy to think: Suppose now be decomposed n, break it down into parts of m. Now put into n 1 and n-1, together with the answer exploded :( 1-n when the number of points system) * (number of decomposition points by the Method 1). 2, and is then divided into n n-2, together with the answer (decomposition method when the number of division n-2) * (number of decomposition points by the Method 2) and so on. Note that the decomposition into 1 to n-1 and n-2 and broken down into two cases 2, should be added. In fact, it should be the idea of ​​partition method.

  The steps of the implementation. First, use fast processing power of x to be decomposed to give the number n, then recursion: 1 into the parts 1, 2 is divided into the parts 1, 2, 3 is divided into the three parts are how many points system, with high fine save up. DETAILED with dt [i] [j] denotes the i j into several parts can Method. Incidentally, Pascal's triangle to take up deposit adjacency matrix, the i-th row and j is the number of i j is decomposed into sub-parts of a method, because the nature of Pascal's triangle is also recursive.

  Here put two versions of the code, easy to understand some of the first; the second plus a high-precision, still for a moment: If I have more than 80,000 adjacency matrix kb, because of space limitations Jizhong OJ solving the problem 65536KB (unlike Los Valley to 125 MB), so together with the rolling array. (Of course, only 65536KB spatial adjacency matrix card out, nothing idle adjacency table, high-precision pressure level or the like are possible w)

With code:

#include <the iostream> 
#include <algorithm> 
#include <CString> 
#include <cstdio>
 #define LL Long Long
 the using  namespace STD; 
LL X; 
int n-, K, MAXN; 
LL dt [ 1100 is ] [ 110 ]; // the i is divided into several (Pascal's triangle where j group 

int KSM ( int a, LL B, int Mo) 
{ 
    int RET = . 1 ;
     the while (B) 
    { 
        IF (B & . 1 ) RET = RET * a% Mo; 
        a = a A% * Mo; 
        b= >> . 1 ; 
    } 
    return RET; 
} 

int main () { 
    CIN >> >> K x;
     int n = x% 1000 ; // find the n-th power x 1000% 
    n = KSM (n, x, 1000 ) ; // find n divided into several (n <= 1000) combinations of k groups 
    for ( int I = . 1 ; I <= n; I ++ ) 
    { 
        dt [I] [ . 1 ] = . 1 ;
         IF (I <= k) 
        dt [I] [I] = . 1 ; 
    } 
    
    for ( int I = 3 ; i <= the n-; i ++) // draw a Pascal's Triangle 3 from start to know why. . 
    {
         For ( int j = 2 ; j <= i && j <= K; j ++) // i is divided into j groups 
        { 
            dt [i] [j] = dt [I- . 1 ] [J- . 1 ] + dt [I- . 1 ] [J]; 
        } 
    } 

    COUT << dt [n-] [K]; 
}

with:

#include<iostream>
#include<algorithm>
#include<cstring>
#define Lovelive long long
using namespace std; 
Lovelive x;
int n,k,maxn;
char dt[2][101][400];
int al[400],bl[400],cl[400];
int first;

int ksm(int a,Lovelive b,int mo)
{
    int ret=1;
    while(b)
    {
        if(B & . 1 ) RET RET = A *% Mo; 
        A = A * A% Mo; 
        B >> = . 1 ; 
    } 
    return RET; 
} 
int main () { 
    CIN >> >> K X;
     int XX = X% 1000 ; // find xx power of x 1000% 
    n = KSM (xx, x, 1000 ); // find the number of combinations of n into k groups (n <= 1000) 
    
    dt [ 0 ] [ . 1 ] [ 0 ] = ' . 1 ' ; 
    dt [ 0 ] [ 2 ] [ 0 ] =' . 1 ' ; 
    
    for ( int i = . 3 ; i <= n-; i ++ ) 
    { 
        for ( int j = 2 ; j <i && j <= K; j ++) // i is divided into j groups 
        { 
            dt [ . 1 -first] [ 1 ] [ 0 ] = ' 1 ' ; // the following is a high-precision operation, the effect is to add two large numbers (nonsense 
            
            Memset (Al, 0 , the sizeof (Al)); 
            Memset (BL, 0 , the sizeof (BL )); 
            Memset (Cl, 0 ,sizeof(cl));
            //dt[i-1][j-1],dt[i-1][j];
            
            int lena=strlen(dt[first][j-1]);
            int lenb=strlen(dt[first][j]);
    
            for(int l=1;l<=lena;l++)
            al[l]=dt[first][j-1][lena-l]-'0';
            for(int l=1;l<=lenb;l++)
            bl[l]=dt[first][j][lenb-l]-'0';
                
            int lenc=1,yu=0;
            while(lenc<=lena||lenc<=lenb)
            {
                cl[lenc]=al[lenc]+bl[lenc]+yu;
                yu=cl[lenc]/10;
                cl[lenc]%=10;
                lenc++;
            }
            cl[lenc]+=yu; 
            if(cl[lenc]==0)lenc--;
                
            int flag=0;
            while(lenc)
            {
                dt[1-first][j][flag]=cl[lenc]+'0';
                lenc--;
                flag++;
            }
        }
        first=1-first;
        
        if(i<=k)
        dt[first][i][0]='1';

    }
    cout<<dt[first][k];
}

 Supplementary Jizhong scores on the OJ: 20 minutes to be messing around, 40 points are strategically no high-precision, 60 in the gap with AC There is no room for optimization

Guess you like

Origin www.cnblogs.com/snowysniper/p/11402777.html
Recommended