#include<bits/stdc++.h> using namespace std; const int N = 3; const int maxn = 1e9; int T; long long n; const long long p= 998244353; struct Matrix{ long long x[N][N]; Matrix operator * (const Matrix& t) const{ Matrix ret; for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ ret.x[i][j] = 0; for(int k = 0; k < N; k++){ ret.x[i][j] += x[i][k] * t.x[k][j] % p; ret.x[i][j] %= p; } } } return ret; } Matrix(){memset(x,0,sizeof x);} Matrix(const Matrix& t){memcpy(x,t.x,sizeof x);} }; Matrix quick_pow(Matrix a,int x){ Matrix ret; memset(ret.x,0,sizeof ret.x); ret.x[0][0] = ret.x[1][1] = ret.x[2][2] = 1; while(x) { if(x&1) ret = ret * a; a = a * a; x >>= 1; } return ret; } int f(){ Matrix m1,m2; m1.x[0][0] = 1; m1.x[0][1] = 0; m1.x[0][2] = 1; m1.x[1][0] = 0; m1.x[1][1] = 1; m1.x[1][2] = 1; m1.x[2][0] = 2; m1.x[2][1] = 2; m1.x[2][2] = 1; m2 = quick_pow(m1,n-1); cout << (m2.x[0][0] + m2.x[0][2] * 2)%p <<endl; } int main(){ cin >> T; for(int i = 0; i< T; i++){ cin >> n; f(); } return 0; }
时间: 2024-04-25 10:26:25 浏览: 125
这段代码是一个矩阵快速幂的模板,用来解决一类递推问题。具体来说,它解决的是以下递推式:
$$f(n)=f(n-1)+f(n-3)+2f(n-2)$$
其中$f(n)$表示第$n$项的值,初始条件为$f(0)=1,f(1)=2,f(2)=4$。
矩阵快速幂的思路是,将递推式转化为矩阵形式:
$$\begin{bmatrix}f(n)\\f(n-1)\\2f(n-2)\end{bmatrix}=\begin{bmatrix}1 & 0 & 1\\0 & 1 & 1\\2 & 2 & 1\end{bmatrix}\begin{bmatrix}f(n-1)\\f(n-2)\\2f(n-3)\end{bmatrix}$$
然后使用矩阵快速幂求解即可。具体来说,将矩阵$\begin{bmatrix}1 & 0 & 1\\0 & 1 & 1\\2 & 2 & 1\end{bmatrix}$作为底数,将$n-1$作为指数,通过快速幂得到$\begin{bmatrix}f(n)\\f(n-1)\\2f(n-2)\end{bmatrix}$的值,最后输出$f(n)$即可。
需要注意的是,由于题目要求对$998244353$取模,因此在矩阵乘法和快速幂的过程中都需要加上取模操作。
相关问题
#include <bits/stdc++.h> using namespace std; const int MAXN = 10001; int a[ MAXN ]; int main() { int n; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a + n); for (int i = 0; i < n; i += 2) if (a[i] != a[i + 1]) { cout << a[i]; break; } return 0; }帮我把这段程序加上注释
下面是加上注释的代码:
```c++
#include <bits/stdc++.h> // 引入所有标准库头文件
using namespace std;
const int MAXN = 10001; // 定义常量 MAXN
int a[MAXN]; // 定义数组 a,长度为 MAXN
int main() {
int n; // 定义变量 n
cin >> n; // 输入 n
for (int i = 0; i < n; i++) // 循环读入 n 个数,存入数组 a 中
cin >> a[i];
sort(a, a + n); // 对数组 a 进行排序
for (int i = 0; i < n; i += 2) // 循环判断相邻两个数是否相等
if (a[i] != a[i + 1]) { // 如果不相等,输出该数并退出循环
cout << a[i];
break;
}
return 0; // 返回 0,表示程序正常结束
}
```
这段程序的功能是找出只出现一次的数字,思路是先将所有数字排序,然后找出第一个不重复的数字。具体实现中,我们先输入数字个数 n 和 n 个数字,然后通过 sort 函数将数组 a 排序。接着,我们循环判断相邻的两个数是否相等,如果不相等就输出该数并退出循环。
修改下列代码#include<bits/stdc++.h> using namespace std; typedef struct LNode { int data; LNode *next; }LNode,*LinkList; typedef struct { … { LNode *p=G.v[i]; while(p->next) { cout<<p->data<<" "; p=p->next; } cout<<p->data<<endl; }
这段代码是一个图的邻接表存储结构的输出函数,但是代码中缺少了图的数据结构定义和初始化,下面是一个完整的代码示例:
```c++
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
typedef struct LNode {
int data;
LNode* next;
} LNode, *LinkList;
typedef struct {
LinkList first;
} VexNode;
typedef struct {
VexNode vexs[MAXN];
int vexnum, arcnum;
} Graph;
void init(Graph& G) {
// 初始化图
G.vexnum = G.arcnum = 0;
for (int i = 1; i <= MAXN; i++) {
G.vexs[i].first = NULL;
}
}
void addEdge(Graph& G, int u, int v) {
// 添加边
LNode* node = new LNode;
node->data = v;
node->next = G.vexs[u].first;
G.vexs[u].first = node;
}
void printGraph(Graph& G) {
// 输出图
for (int i = 1; i <= G.vexnum; i++) {
LNode* p = G.vexs[i].first;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
}
int main() {
Graph G;
init(G);
G.vexnum = 5;
G.arcnum = 5;
addEdge(G, 1, 2);
addEdge(G, 1, 3);
addEdge(G, 2, 4);
addEdge(G, 3, 4);
addEdge(G, 4, 5);
printGraph(G);
return 0;
}
```
在这个示例中,我们定义了图的数据结构 `Graph`,其中包括了顶点数组 `vexs` 和边的数量信息 `vexnum` 和 `arcnum`。`init` 函数用于初始化图,将顶点数组的 `first` 域初始化为 `NULL`。`addEdge` 函数用于添加边,具体实现是将一个节点插入到邻接表中。`printGraph` 函数用于输出图的邻接表存储结构。在主函数中,我们定义了一个 `Graph` 对象 `G`,并且添加了一些边,最后调用 `printGraph` 函数输出邻接表。
阅读全文