TC704div2 C ModEquationEasy 矩阵快速幂+dp

Problem Statement

     You are given the ints nK, and v



Consider the following modular equation with n variables: (x[0] * x[1] * x[2] * ... * x[n-1]) mod K = v. How many solutions does it have? 



Formally, we want to find the number of sequences (x[0], x[1], ..., x[n-1]) such that each x[i] is an integer between 0 and K-1, inclusive, and the product of all x[i] gives the remainder v when divided by K



Please compute and return the number of such sequences, modulo 10^9+7.

Definition

    
Class: ModEquationEasy
Method: count
Parameters: int, int, int
Returns: int
Method signature: int count(int n, int K, int v)
(be sure your method is public)

Limits

    
Time limit (s): 2.000
Memory limit (MB): 256
Stack limit (MB): 256

Constraints

- n will be between 1 and 1,000,000,000, inclusive.
- K will be between 2 and 100, inclusive.
- v will be between 0 and (K-1), inclusive.

Examples

0)  
    
2
4
1
Returns: 2
The input describes the modular equation (x[0] * x[1]) mod 4 = 1. 



There are two solutions: (1, 1) and (3, 3).
1)  
    
2
4
0
Returns: 8
This time we have 8 solutions: (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (2, 0), (3, 0) and (2, 2).
2)  
    
2
4
2
Returns: 4
 
3)  
    
3
7
5
Returns: 36
 
4)  
    
10
100
50
Returns: 683036071
 
5)  
    
1
2
0
Returns: 1
 

题意:

给你n,v,k,找出n个数,使得 (x[0] * x[1] * x[2] * ... * x[n-1]) mod K = v,其中x[i]在0~k之间

思路:

mat[i][j]:=最后一个数取成i,余数为j的个数

转移: mat[i][j] = mat[i][j]+mat[i][k]*mat[k][j];

用K*K的矩阵表示,每乘一次代表取了下一个数。

最后的答案是 mat[i][v] {0<=i<=k}

代码:

 1 int N,K,V;
 2 struct node{
 3     ll m[105][105];
 4     void clear(){
 5         mem(m);
 6     }
 7 }a;
 8 
 9 node mul(node a,node b){
10     node re; re.clear();
11     for(int i=0; i<K; i++)
12         for(int k=0; k<K; k++){
13             if(a.m[i][k]){
14                 for(int j=0; j<K; j++)
15                     re.m[i][j] = (re.m[i][j]+(a.m[i][k]*b.m[k][j])%mod)%mod;
16             }
17         }
18     return re;
19 }
20 
21 node qpow(int k){
22     node re; re.clear();
23     for(int i=0; i<=K; i++) re.m[i][i]=1;
24     while(k){
25         if(k&1) re = mul(re,a);
26         a = mul(a,a);
27         k >>= 1;
28     }
29     return re;
30 }
31 
32 int count(int n, int k, int v)  
33 {
34     N=n,K=k,V=v;
35     a.clear();
36      for(int i=0; i<K; i++){
37          for(int j=0; j<K; j++)
38              a.m[i][i*j%K]++;
39      }   
40      a = qpow(n-1);
41      ll ans = 0;
42      for(int i=0; i<K; i++){
43          ans = (ans+a.m[i][v])%mod;
44      }
45      return ans;
46 }  
原文地址:https://www.cnblogs.com/yxg123123/p/6837711.html