COJ 1208 矩阵快速幂DP

  题目大意:

f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和

由于n极大,所以考虑矩阵快速幂加速

我们要求解最后的sum[n]

首先我们需要思考

sum[n] = sum[n-1] + f(i+1)^k

那么很显然sum[n-1]是矩阵中的一个元素块

那么f(i+1)^k怎么利用f(i) , f(i-1)来求

f(i+1)^k = (f(i) + f(i-1)) ^ k

假如k = 1 , 可以看出f(i+1) = f(i-1) + f(i) (1,1)

      k = 2 , 可以看出f(i+1)^2 = f(i-1)^2 + 2*f(i-1)*f(i) + f(i)^2 (1 , 2 , 1)

后面只列出前面的因子 k=3          1 , 3 , 3 , 1

          k =4          1, 4 ,6,4,1

        很容易看出后一行的数是由前一行的数当前列和前一列的相加

那么这里要放入矩阵中思考的就是 f(i-1)^k , f(i-1)^(k-1)*f(i) ...... f(i)^k , sum[i] 这样 k+2 个元素

那么做矩阵快速幂就是利用f(i-1)^k , f(i-1)^(k-1)*f(i) ...... f(i)^k , sum[i]  乘以某一个矩阵得到

f(i)^k , f(i)^(k-1)*f(i+1) ...... f(i+1)^k , sum[i+1]

自己一个个递推就会渐渐利用上述的关系轻松得到这个矩阵

 

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 using namespace std;
 5 #define N 100
 6 #define ll long long
 7 const int MOD = 1000000007;
 8 int n , k , l;
 9 int num[N];
10 
11 struct Matrix{
12     int a[N][N];
13     Matrix operator*(const Matrix &m) const{
14         Matrix ans ;
15         for(int i=0 ; i<l ; i++){
16             for(int j=0 ; j<l ; j++){
17                 ans.a[i][j] = 0;
18                 for(int k=0 ; k<l ; k++){
19                     ans.a[i][j] += ((ll)a[i][k] * m.a[k][j])%MOD;
20                     ans.a[i][j] %= MOD;
21                 }
22             }
23         }
24         return ans;
25     }
26 }st;
27 
28 Matrix q_pow(Matrix b , int t)
29 {
30     Matrix ans;
31     memset(ans.a , 0 , sizeof(ans));
32     for(int i=0 ; i<l ; i++) ans.a[i][i] = 1;
33     while(t)
34     {
35         if(t&1) ans = ans*b;
36         b = b*b;
37         t>>=1;
38     }
39     return ans;
40 }
41 
42 void build_matrix()
43 {
44     memset(st.a , 0 , sizeof(st.a));
45     st.a[l-2][0] = 1;
46     for(int i=1 ; i<l-1 ; i++){
47         for(int j=l-2 , t=0 ; t<=i ; t++,j--){
48             st.a[j][i] = st.a[j][i-1]+st.a[j+1][i-1];
49         }
50     }
51     for(int i=0 ; i<l-1 ; i++)
52         st.a[i][l-1] = st.a[i][l-2];
53     st.a[l-1][l-1] = 1;
54 }
55 
56 int main()
57 {
58     #ifndef ONLINE_JUDGE
59         freopen("a.in" , "r" , stdin);
60     #endif // ONLINE_JUDGE
61     int T;
62     scanf("%d" , &T);
63     while(T--)
64     {
65         scanf("%d%d" , &n , &k);
66         l = k+2;
67         build_matrix();
68         for(int i=0 ; i<l-1 ; i++){
69             num[i] = 1;
70         }
71         num[l-1] = 2;
72         if(n<=2) printf("%d\n" , n);
73         else{
74             Matrix ans = q_pow(st , n-2);
75             int ret = 0;
76             for(int i=0 ; i<l ; i++){
77                 ret += num[i]*ans.a[i][l-1]%MOD;
78                 ret %= MOD;
79             }
80             printf("%d\n" , ret);
81         }
82     }
83     return 0;
84 }

 

 

 

转载于:https://www.cnblogs.com/CSU3901130321/p/4537453.html

### XTU Online Judge 字符矩阵题目解析 #### 题目描述 对于字符矩阵类问题,XTU Online Judge 平台上有两个典型例子。第一个是关于ASCII码的输出格式化[^1]: - 输出行号采用十六进制表示,宽度固定为五位,不足部分用零填充。 - 行号之后跟一个空格。 - 接下来每行最多显示32个字符对应的ASCII码值,同样以两位宽的大写字母形式呈现。 另一个案例涉及RGB颜色模式下的字符串处理[^2]: - 输入一段由'R', 'G' 和'B'组成的序列。 - 计算特定区间内不同字母的数量变化情况。 这两个实例展示了如何通过不同的逻辑来操作和展示字符数据。 #### 解决方案示例:ASCII 码转换与格式化输出 针对ASCII编码的任务需求,下面给出Python实现方法: ```python def format_ascii_output(text): lines = [] line_number = 0 while text: chunk = text[:32] hex_values = " ".join(f"{ord(c):02X}" for c in chunk) formatted_line_num = f"{line_number:05X}" combined_line = f"{formatted_line_num} {hex_values.rstrip()}" lines.append(combined_line) text = text[32:] line_number += 1 result = "\n".join(lines).rstrip() return result sample_text = "This is a sample string to demonstrate ASCII formatting." print(format_ascii_output(sample_text)) ``` 此函数接收任意长度的文字串作为参数,并按照指定规则将其转化为多行带有编号及相应ASCII码表征的结果集。 #### 解决方案示例:RGB 出现频率计算 对于RGB类型的挑战,则可以利用字典记录各阶段内的字符频次分布状况: ```python from collections import Counter def rgb_frequency(s): r_end = s.find('G') g_start, g_end = r_end, s.find('B', r_end) b_start = g_end counters = [ ('R1 R2', (s[:r_end], s[r_end:g_start])), ('G1 G2', (s[g_start:g_end], s[g_end:b_start])), ('B1 B2', (s[b_start:], "")) ] results = {} for label, parts in counters: part_counts = tuple(Counter(part)['R'] for part in parts), \ tuple(Counter(part)['G'] for part in parts), \ tuple(Counter(part)['B'] for part in parts) flat_results = sum([list(x) for x in zip(*part_counts)], []) results[label.replace(" ", "")] = list(map(str,flat_results)) output_string = ",".join(["=".join(item) for item in results.items()]) print(output_string) rgb_sequence = "RRGBBBGGGR" rgb_frequency(rgb_sequence) ``` 上述代码片段实现了对给定RGB序列中各个分段内字符数量的具体统计工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值