ACM-ICPC 2018 焦作赛区网络预赛 G 隔板+费马小定理 J 牛顿迭代法+java开平方根 K 背包 L矩阵快速幂

版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82716847

G

思路:隔板法知道结果是 2 ^ ( n - 1 ),n过大。
费马小定理为 a^(p-1) ≡ 1 mod p ; a, p 互质,p为质数。
所以2^(p-1)% p 为1,2^k*(p-1) % p 也为1,所以找出n = k*(p-1) + m 。只需要求2 ^ m 即可。

Code:

#include <bits/stdc++.h>
#define LL long long 
#define mod 1000000007
using namespace std;
char s[1000006];
LL quick( LL a , LL k ){
    LL ans = 1LL ;
    while( k ){
        if( k & 1 ){
            ans = ( ans * a ) % mod ;
        }
        k >>= 1 ;
        a = ( a * a ) % mod;
    }
    return ans ;
}

int main(){
    int T;
    scanf("%d",&T);
    while( T-- ){
        scanf("%s",s);
        LL len = strlen(s);
        LL m = mod - 1;
        LL id = s[0]-'0';
        for( LL i = 1 ; i < len ; i++ ){
            id = ( id * 10 + ( s[i] - '0' ) ) % m;  
        } 
        if( id == 0 ) printf("0\n");
        else printf("%lld\n",quick(2,id-1));
    }
    return 0;
} 

J
思路:牛顿迭代+java
Code:

import java.util.* ; 
import java.math.* ;
public class Main{
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        int T = cin.nextInt();
        for( int i = 0 ; i < T ; i++ ){
            BigInteger n = cin.nextBigInteger();
            BigInteger x = cal( n ) ;
            BigInteger y = n.multiply(n.subtract(BigInteger.valueOf(1))).shiftRight(1);
            BigInteger z = cal( y ) ; 
            boolean L = x.multiply(x).equals(n) ;
            boolean R = z.multiply(z).equals(y) ;
            if(  L ){
                if( R ){
                    System.out.println("Arena of Valor");
                }else{
                    System.out.println("Hearth Stone");
                }
            }else{
                if( R ){
                    System.out.println("Clash Royale");
                }else{
                    System.out.println("League of Legends");
                }
            }
        }
    }

    static BigInteger cal( BigInteger x ){
        BigInteger ans = BigInteger.valueOf(0);
        if( x.equals(BigInteger.valueOf(0)) ) return ans ;
        BigInteger now = BigInteger.valueOf(1);
        BigInteger last = BigInteger.valueOf(-1);
        while( true ){
            BigInteger nxt = now.add(x.divide(now)).shiftRight(1);
            if( nxt.equals(last) ){
                if( last.compareTo(now) == -1 ){
                    return last ;
                }else return now; 
            }
            last = now ; 
            now = nxt ;
        }
    }

}

K
思路:完全背包统计方案数
Code:

#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e4 + 66 ;
const int MOD = 1e9 + 7 ;
int dp[MAX] ;
int fac[MAX];
void init(){
    fac[0] = 1 ;
    for( int i = 1 ; i < 22 ; i++ ){
        fac[i] = fac[i-1] * 2 ; 
    }
}
int main(){
    int T ;
    int v , c ; 
    init();
    scanf("%d",&T);
    int n , q ; 
    while( T -- ){
        memset( dp , 0 , sizeof(dp) ) ; dp[0] = 1 ;
        scanf("%d%d",&n,&q);
        for( int i = 0 ; i < n ; i++ ){
            scanf("%d%d",&v,&c);
            for( int j = 0 ; j < c ; j++ ){
                for( int k = MAX - 2 ; k >= fac[j] * v ; k-- ){
                    dp[k] = ( dp[k] + dp[k-fac[j]*v] ) % MOD ;
                }
            }
        }
        int x ;
        while( q-- ){
            scanf("%d",&x);
            printf("%d\n",dp[x]);
        }
    }
    return 0 ;
}

L
思路 :可以得到有7种长度为3的情况不能使用, 长度为2共有9种,cf , cm , mc , mf , fc , fm , ff, mm , cc
在加一个长度时,得到的合法情况数量分别为,2 2 2 3 2 3 2 2 2
以后每增加一个时就是再重复此过程,根据对应关系写一个9*9矩阵。
用矩阵快速幂计算。
Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7;
int t ; 
ll n ;
struct Matrix{
    ll m[9][9];
    Matrix(){
        memset(m, 0, sizeof(m));
    }
};

Matrix mul( Matrix &A, Matrix &B ) {
    Matrix C;
    for(int i = 0; i < 9; i++) {
        for(int j = 0; j < 9; j ++) {
            for(int k = 0; k < 9; k ++) {
                C.m[i][j] = (C.m[i][j] + A.m[i][k]*B.m[k][j]) % mod;
            }
        }
    }
    return C;
}

Matrix pow( Matrix A, ll n ) {
    Matrix B;
    for(int i = 0; i < 9; i ++) B.m[i][i] = 1;
    while( n ) {
        if( n & 1 ) B = mul(B, A);
        A = mul(A, A);
        n >>= 1;
    }
    return B;
}
int main() {
    Matrix A;
    A.m[0][5] = A.m[0][7] = A.m[1][3] = A.m[1][5] = A.m[1][7] = 1;
    A.m[2][4] = A.m[2][6] = A.m[3][0] = A.m[3][6] = 1;
    A.m[4][1] = A.m[4][8] = A.m[5][1] = A.m[5][2] = A.m[5][8] = 1;
    A.m[6][0] = A.m[6][4] = A.m[7][3] = A.m[7][5] = A.m[8][1] = A.m[8][2] = 1;
    int T;
    scanf("%d",&T);
    while( T -- ){
        scanf("%lld", &n);
        if( n == 1 ) {
            printf("3\n");
            continue ;
        }
        Matrix B = pow( A , n - 2 );
        ll ans = 0LL;
        for( int i = 0 ; i < 9 ; i++ ){
            for( int j = 0 ; j < 9 ; j++ ){
                ans = ( ans + B.m[i][j] ) % mod ;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/FrankAx/article/details/82716847