2019南昌网络赛H.The Nth Item

链接

点击跳转

题解

特征根法解除斐波那契额通项:

根据递推式 F ( n ) = 3 F ( n − 1 ) + 2 F ( n − 2 ) F(n)=3F(n-1)+2F(n-2) F(n)=3F(n1)+2F(n2)
x 2 = 3 x + 2 x^2 = 3x + 2 x2=3x+2

解得 x 1 = 3 − 17 2 , x 2 = 3 + 17 2 x_1=\frac{3-\sqrt {17} }{2},x_2=\frac{3+\sqrt {17} }{2} x1=2317 ,x2=23+17

F ( n ) = c 1 x 1 n + c 2 x 2 n F(n) = c_1x_1^n + c_2x_2^n F(n)=c1x1n+c2x2n

F ( 0 ) = 0 , F ( 1 ) = 1 F(0)=0,F(1)=1 F(0)=0,F(1)=1带入,解得 c 1 = − 17 17 , c 2 = 17 17 c1=-\frac{\sqrt {17} }{17},c2=\frac{\sqrt {17} }{17} c1=1717 ,c2=1717

所以 F ( n ) = − 17 17 ( 3 − 17 2 ) n + 17 17 ( 3 + 17 2 ) n F(n) = -\frac{\sqrt {17} }{17} (\frac{3-\sqrt {17} }{2})^n + \frac{\sqrt {17} }{17} (\frac{3+\sqrt {17} }{2})^n F(n)=1717 (2317 )n+1717 (23+17 )n

首先可以对 n n n欧拉降幂,然后用 b i g − s m a l l big-small bigsmall的方法预处理 x 1 , x 2 x_1,x_2 x1,x2的幂,每次就可以 O ( 1 ) O(1) O(1)回答了

代码

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 100010
#define cl(x) memset(x,0,sizeof(x))
#define rep(_,__) for(_=1;_<=(__);_++)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define mod 998244353ll
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
ll fastpow(ll a, ll b, ll c)
{
    ll t(a%c), ans(1ll);
    for(;b;b>>=1,t=t*t%c)if(b&1)ans=ans*t%c;
    return ans;
}
ll Q, N, r=473844410, a, b, big[2][maxn], small[2][maxn], _r=fastpow(r,mod-2,mod);
int main()
{
    ll i, S=100000, lastans=0, ans=0;
    a=(3-r+mod)*fastpow(2,mod-2,mod)%mod;
    b=(3+r)*fastpow(2,mod-2,mod)%mod;
    big[0][0]=big[1][0]=1;
    small[0][0]=small[1][0]=1;
    rep(i,S)
    {
        big[0][i]=fastpow(a,S*i,mod)%mod;
        big[1][i]=fastpow(b,S*i,mod)%mod;
        small[0][i]=small[0][i-1]*a%mod;
        small[1][i]=small[1][i-1]*b%mod;
    }
    Q=read(), N=read();
    while(Q--)
    {
        N ^= lastans*lastans;
        ll n = N % (mod-1);
        lastans = _r *( -big[0][n/S]*small[0][n%S]%mod + big[1][n/S]*small[1][n%S]%mod + mod ) %mod;
        ans ^= lastans;
    }
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`_.nth` 函数是 Lodash 中的一个工具函数,用于获取数组 `array` 中第 `num` 个元素。它的源码实现如下: ```javascript function nth(array, n) { var length = array == null ? 0 : array.length if (!length) { return } n += n < 0 ? length : 0 return isIndex(n, length) ? array[n] : undefined } ``` 该函数首先判断传入的数组是否为空,如果为空则直接返回 `undefined`。然后对传入的 `num` 进行一些处理,如果 `num` 是负数,则将其转化为正数。最后,通过 `isIndex` 函数判断 `num` 是否为有效的下标,如果是,则返回对应元素,否则返回 `undefined`。 其中,`isIndex` 函数的实现如下: ```javascript function isIndex(value, length) { var type = typeof value length = length == null ? MAX_SAFE_INTEGER : length return !!length && (type === 'number' || (type !== 'symbol' && reIsUint.test(value))) && (value > -1 && value % 1 == 0 && value < length) } ``` 该函数用于判断一个值是否为有效的数组下标。它首先判断传入的 `length` 是否为有效的数字,然后判断 `value` 是否为有效的数字或字符串,并且在范围内。如果满足以上条件,则返回 `true`,否则返回 `false`。 需要注意的是,`reIsUint` 是一个正则表达式,用于判断一个字符串是否表示一个非负整数: ```javascript var reIsUint = /^(?:0|[1-9]\d*)$/ ``` 综上所述,`_.nth` 函数是一个简单实用的工具函数,用于获取数组中指定位置的元素,并且具有较好的健壮性和可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值