版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82716847
思路:隔板法知道结果是 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;
}