The Nth Item(矩阵快速幂(非结构体))

The Nth Item(矩阵快速幂(非结构体))_第1张图片
The Nth Item(矩阵快速幂(非结构体))_第2张图片
这道题题意很简单;但是如果你用struct矩阵快速幂就是t,我就是QAQ;最后自己手写了两个函数来搞快速幂,然后才AC的;
因为我发现如果用结构体的话,那么就会调用复制构造函数,这样时间复杂度就上升了;
现在说说这道题的意思吧:
题意:就是上面那个等式,很明显如果以前有经验的一看就是矩阵快速幂:
可以很明显的构造出一个矩阵出来:
The Nth Item(矩阵快速幂(非结构体))_第3张图片
然后就可以知道它:
The Nth Item(矩阵快速幂(非结构体))_第4张图片
如果你不清楚为什么是n-1的话,你可以这样想一想;
如果n取3;那么就是:
The Nth Item(矩阵快速幂(非结构体))_第5张图片
所以可以推出来指数为n-1;
然后就很简单了直接矩阵快速幂就OK了;
但是你会发现t了?why????
其实比赛的时候我也不知道为啥;但是赛后我才知道因为n是异或的值,所以可能异或到以前出现过的值,如果以前出现过n了,那么我就不需要计算了吧;所以我就可以用一个map来标记是否算过以n-1为指数的矩阵快速幂;就不用再去算了,所以可以自己手写三个函数去实现快速幂;那么最后答案就是Fn=a[0][0]*F1+a[0][1]*F0;可以知道F0=0所以就没必要写后面的了;就直接:
Fn=a[0][0]*F1;
所以这道题就AC了,说实话这个题也是比较坑的,1.重复出现,2.结构体快速幂有复制构造函数所以就不能用struct去写;
以后吸取教训了,快速幂最好都自己去手写一遍,免得t了;
常识补充其实map还可以用unordered_map来标记,只不过这里没用到查找功能,所以一个简单的map就够了;
AC代码:

#include
using namespace std;
typedef long long ll;
const int Mod=998244353;
#define N 2//这里表示2*2的矩阵//如果是3*3的  则可以令为N 3 
map A;
ll a[N][N],one[N][N],t[N][N];//a是初始化矩阵,one是单位矩阵,t是临时矩阵
void Multiply(ll b[N][N],ll c[N][N]){//求两个矩阵相乘存在b中 ,因为二维数组传的是首地址,所以实参会被修改
    for(int i=0;i>=1;
	   } 
}
void init(){//初始化构造矩阵+单位矩阵
	  a[0][0]=3;a[0][1]=2;a[1][0]=1;//初始化矩阵 
	  a[1][1]=0;
	  one[1][0]=one[0][1]=0;
	  for(int i=0;i<2;i++)one[i][i]=1;//初始化单位矩阵 
}
int main(){
		ios::sync_with_stdio(false);//关闭同步
	ll f1=1;
	ll Q,n,ans=0;
	cin>>Q>>n;
	while(Q--){
        if(A[n]){//检查是否以n-1为幂是否计算过了
        	ans^=A[n];
		}else{
			init();
			QP(a,n-1);
			A[n]=one[0][0]*f1;
			ans^=A[n];
			n=n^(A[n]*A[n]); 
		}   
    }
   prinf("%lld",ans);//输出答案
	return 0;
}

你可能感兴趣的:(矩阵快速幂)