C. DZY Loves Fibonacci Numbers(线段树&fibonacci)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C. DZY Loves Fibonacci Numbers(线段树&fibonacci)相关的知识,希望对你有一定的参考价值。
C. DZY Loves Fibonacci Numbers(线段树&fibonacci)
考虑 f i b o n a c c i fibonacci fibonacci的几个性质:
- 两个的广义斐波那契数列和仍是广义斐波那契数列。
- 对于广义斐波那契数列:
g
[
a
,
b
]
g[a,b]
g[a,b],
(
a
,
b
)
(a,b)
(a,b)分别是第一项和第二项。有
- g n = f n − 2 × a + f n − 1 × b g_n=f_n-2\\times a+f_n-1 \\times b gn=fn−2×a+fn−1×b
- ∑ i = 1 n g i = g n + 2 − g 2 \\sum\\limits_i=1^n g_i=g_n+2-g_2 i=1∑ngi=gn+2−g2
因此,每次区间加 [ l , r ] [l,r] [l,r]操作,我们可以用线段树维护每段区间的 g 1 , g 2 , s u m g_1,g_2,sum g1,g2,sum 分别是这段区间的广义 f i b fib fib第一项和第二项,与区间和。
对于合并子树操作就是:
a [ r t ] . s = a [ l s o n ] . s + a [ r s o n ] . s + ∑ i = l r g i a[rt].s=a[lson].s+a[rson].s+\\sum\\limits_i=l^r g_i a[rt].s=a[lson].s+a[rson].s+i=l∑rgi
令 l e n = r − l + 1 len=r-l+1 len=r−l+1
而 ∑ i = l r = g l e n + 2 − g 2 = f [ l e n ] × g 1 + f [ l e n + 1 ] × g 2 \\sum\\limits_i=l^r=g_len+2-g_2=f[len]\\times g_1+f[len+1]\\times g_2 i=l∑r=glen+2−g2=f[len]×g1+f[len+1]×g2
所以可以 O ( 1 ) O(1) O(1) 合并。
至于下传影响:
左子树的 g 1 , g 2 g_1,g_2 g1,g2显然直接根据性质1直接加。
右子树类似地,加上对应的 g m i d + 1 , g m i d + 2 g_mid+1,g_mid+2 gmid+1,gmid+2 m i d + 1 mid+1 mid+1也就是右子树的 L L L左端点。
而 g m i d + 1 = f m i d − 1 × g 1 + f m i d × g 2 ) g_mid+1=f_mid-1\\times g_1+f_mid\\times g_2) gmid+1=fmid−1×g1+fmid×g2)
g m i d + 1 g_mid+1 gmid+1 同理。
il void pd(int x)
if(a[x].f1||a[x].f2)
a[lx].f1+=a[x].f1,a[lx].f2+=a[x].f2;
//加上 a[mid+1].val
a[rx].f1+=a[x].f1*f[len(lx)-1]+a[x].f2*f[len(lx)];
//加上 a[mid+2].val
a[rx].f2+=a[x].f1*f[len(lx)]+a[x].f2*f[len(lx)+1];
re(lx),re(rx);
a[x].f1=a[x].f2=0;
时间复杂度: O ( m l o g n ) O(mlogn) O(mlogn)
// Problem: C. DZY Loves Fibonacci Numbers
// Contest: Codeforces - Codeforces Round #FF (Div. 1)
// URL: https://codeforces.com/problemset/problem/446/C
// Memory Limit: 256 MB
// Time Limit: 4000 ms
// Date: 2021-11-27 17:04:10
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=3e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+9;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
int n,m;
ll f[N];
void init()
f[1]=f[2]=1;
rep(i,3,n+1) f[i]=(f[i-1]+f[i-2])%mod;
//区间修改 区间求和
#define il inline
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
struct SegTree
struct node
int l,r;
ll f1,f2;
ll s;
a[N<<4];
il void re(int x)
a[x].f1%=mod,a[x].f2%=mod;
a[x].s=a[lx].s+a[rx].s+(a[x].f1*f[len(x)]+a[x].f2*以上是关于C. DZY Loves Fibonacci Numbers(线段树&fibonacci)的主要内容,如果未能解决你的问题,请参考以下文章
[CodeForces - 447E] E - DZY Loves Fibonacci Numbers
CF446C DZY Loves Fibonacci Numbers 线段树 + 数学
Codeforces446C - DZY Loves Fibonacci Numbers