题目解释
现有一数列:
题目思路分析
抛开复杂度不谈,这道题可以用矩阵加速(矩阵的快速幂)和通项公式两种方法来做,这两种方法求一个
总时间复杂度:
矩阵加速:O(
通项公式:O(
而本题的T最大范围为[1,5e7],而n的最大可到
因此整体思路为:先推通项公式,再用光速幂优化查询
通项公式推导
同理
代码实现
由于通项中所有幂的底数均为3,因此可以用光速幂预处理
其实现原理为
具体实施如下
#define Q 32000
//预处理
gsm1[0]=gsm2[0]=1;
for(int i=1;i<=Q;i++)gsm1[i]=1ll*gsm1[i-1]*3%mod;
for(int i=1;i<=Q;i++)gsm2[i]=1ll*gsm2[i-1]*gsm1[Q]%mod;
//调用
int gsm(int n){
return 1ll*gsm2[n/Q]*gsm1[n%Q]%mod;
}
由于答案需要取模,除以一个数需改为乘以它的逆元,所以我们可以通过快速幂计算得32在1e9+7下的逆元为281250002(即
而由于有时n过大,我们可以利用
最后,计算时记得乘上1ll,每算一次都要取一次模防止超出long long的范围
AC代码
#include<bits/stdc++.h>
#define mod 1000000007
#define _32 281250002
#define Q 32000
using namespace std;
int gsm1[Q+1],gsm2[Q+1],rst,T;
int gsm(int n){
return 1ll*gsm2[n/Q]*gsm1[n%Q]%mod;
}
namespace Mker
{
// Powered By Kawashiro_Nitori
// Made In Gensokyo, Nihon
#include<climits>
#define ull unsigned long long
#define uint unsigned int
ull sd;int op;
inline void init() {scanf("%llu %d", &sd, &op);}
inline ull ull_rand()
{
sd ^= sd << 43;
sd ^= sd >> 29;
sd ^= sd << 34;
return sd;
}
inline ull rand()
{
if (op == 0) return ull_rand() % USHRT_MAX + 1;
if (op == 1) return ull_rand() % UINT_MAX + 1;
if (op == 2) return ull_rand();
}
}
int comput(unsigned long long x){
if(x&1)return 1ll*(1ll*(36*(x%mod)-117+mod)%mod*gsm(x%(mod-1))+51)%mod*_32%mod;
return 1ll*(1ll*(36*(x%mod)-117+mod)%mod*gsm(x%(mod-1))+21)%mod*_32%mod;
}
int main(){
scanf("%d",&T);
Mker::init();
gsm1[0]=gsm2[0]=1;
for(int i=1;i<=Q;i++)gsm1[i]=1ll*gsm1[i-1]*3%mod;
for(int i=1;i<=Q;i++)gsm2[i]=1ll*gsm2[i-1]*gsm1[Q]%mod;
while(T--){
rst^=comput(Mker::rand());
}
printf("%d",rst);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现