wanxue

博客园 首页 新随笔 联系 订阅 管理
  7 随笔 :: 0 文章 :: 0 评论 :: 110 阅读

题目解释

现有一数列:a0=3,a1=6,a2=12,an=3an1+an23an3+3nTanmod p 的异或和

题目思路分析

抛开复杂度不谈,这道题可以用矩阵加速(矩阵的快速幂)和通项公式两种方法来做,这两种方法求一个an的时间复杂度都是log2(n),但矩阵乘法需要更多时间,因此常数略大

总时间复杂度:

矩阵加速:O(16Tlog2n)
通项公式:O(Tlog2n)
而本题的T最大范围为[1,5e7],而n的最大可到2631,很显然,总时间复杂度的需求为O(n),尽管上述两种做法用快速幂实现都会TLE,但通项公式中的幂的底数固定,可以用光速幂预处理
因此整体思路为:先推通项公式,再用光速幂优化查询

通项公式推导

an=3an1+an23an3+3n
anan2=3(an1an3)+3n
anan2=bnb2=9
bn=3bn1+3n
bn3n=bn13n1+1
bn3n=cnc2=1
cn=cn1+1
cn=c0+n=c2+n2=1+n2=n3
bn=(n3)3n
anan2=(n3)3n
nan=a0+i=1n2(2i3)32i=3+i=1n2(2i3)32i

i=1n2(2i3)32i=X

9X=9sumi=1n2(2i3)32i=sumi=1n2(2i3)32i+2

8X=9XX=sumi=1n2(2i3)32i+2sumi=1n2(2i3)32i

8X=(n3)3(n+2)+sumi=1n21(2i3)32i+2sumi=2n2(2i3)32i+9

8X=(n3)3(n+2)sumi=2n2(2i3[2(i1)3])32i+9

8X=(n3)3(n+2)sumi=2n2232i+9

8X=(n3)3(n+2)3(n+2)348+9

X=(4n13)3(n+2)+11732

an=(4n13)3(n+2)+117323=(36n117)3n+2132

nan=a1+i=1n2(2i3)32i

同理an=(4n13)3(n+2)+5132=(36n117)3n+5132

代码实现

由于通项中所有幂的底数均为3,因此可以用光速幂预处理
其实现原理为an=akx+y=akxay,分别预处理akxay
具体实施如下

#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(即321e9+5mod1e9+7
而由于有时n过大,我们可以利用ana(n1)modp(modp))来化简
最后,计算时记得乘上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);
}
posted on   thelatersnow  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示