数列

31 篇文章 0 订阅
29 篇文章 0 订阅

【简要题意】有两个数列{x},{y},满足 x 0 = y 0 = 1 x_0=y_0=1 x0=y0=1数论递推式:
x n = x n − 1 2 + x n − 1 , y n = y n − 1 2 1 + 2 y n − 1 , ( n ≥ 1 ) x_n=\frac{x_{n-1}}{2+x_{n-1}},y_n=\frac{y^2_{n-1}}{1+2y_{n-1}},(n≥1) xn=2+xn1xn1,yn=1+2yn1yn12,(n1)
现在给定n,求m使得 x m = y n x_m=y_n xm=yn
如果输出大于maxlongint输出其位数

【分析】
先打表找规律,有:

012345
x11/31/71/151/311/63
y11/31/151/225······

发现有通项公式:
x n = 2 n + 1 − 1 , y n = 2 2 n − 1 , ( n ≥ 0 ) x_n=2^{n+1}-1,y_n=2^{2^n}-1,(n≥0) xn=2n+11,yn=22n1,(n0)
由于指数函数在R上是单调函数,所以得到结论:
m = 2 n − 1 m=2^n-1 m=2n1
由于2的幂个位为2、4、8、6,所以不用考虑退位。
n<=31时直接左移输出即可,否则手动模拟科学计数法(不在乎精度缺失,逃)

【code】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
struct node{
	long double num;
	LL len;
};
node operator*(node x,node y){
	node ret;
	ret.num=x.num*y.num;
	ret.len=x.len+y.len;
	while(ret.num>=10) ret.num=ret.num/10,ret.len++;
	return ret;
}
LL n,m;
inline LL pow(node x,LL p){
	node ret=(node){1,0};
	while(p>0){
		if(p&1) ret=ret*x;
		x=x*x,p=p>>1;
	}
	return ret.len+1;
}
int main(){
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	cin>>n;
	if(n<=31) cout<<(1<<n)-1<<endl;
	else cout<<pow((node){2,0},n)<<endl;
	return 0;
}

还有一种做法是直接log运算,也放一下代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read(){
	int u=0,f=1;char c=getchar();
	while(c<'0'||c>'9') f=(c=='-'?-1:1),c=getchar();
	while(c>='0'&&c<='9') u=(u<<1)+(u<<3)+c-'0',c=getchar();
	return u*f;
}
int n;
int main(){
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	n=read();
	if(n<=31) cout<<(1ll<<n)-1;
	else cout<<(int)(n*(log(2)/log(10))+1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值