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=fn2×a+fn1×b
    • ∑ i = 1 n g i = g n + 2 − g 2 \\sum\\limits_i=1^n g_i=g_n+2-g_2 i=1ngi=gn+2g2

因此,每次区间加 [ 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=lrgi

l e n = r − l + 1 len=r-l+1 len=rl+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=lr=glen+2g2=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=fmid1×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

题解 CF446C DZY Loves Fibonacci Numbers

A. DZY Loves Chessboard

DZY Loves Chemistry (并查集)