首页 > 其他分享 >CF446C. DZY Loves Fibonacci Numbers

CF446C. DZY Loves Fibonacci Numbers

时间:2023-05-20 16:13:57浏览次数:41  
标签:right frac int dfrac sum sqrt Fibonacci DZY CF446C

好牛的题,写一下。

题意:维护一个序列 \(a\),长度为 \(n\),有 \(m\) 次操作:

  • 1 l r:对于 \(i\in[l,r]\),\(a_i\leftarrow a_i+f_{i-l+1}\)。

  • 2 l r:求 \(\displaystyle\left(\sum_{i=l}^ra_i\right)\bmod(10^9+9)\)。

其中 \(f_{i}\) 表示第 \(i\) 个斐波那契数(\(f_0=0,f_1=1,f_n=f_{n-1}+f_{n-2}(n\ge2)\))。

\(1\le n,m\le3\times10^5\),\(1\le a_i\le10^9\)。

读完题后,我们不难猜到这个题应该要用线段树来维护。那怎么做到区间加等比数列呢?

我们发现,如果能求出 \(f_n\) 的通项公式,区间加的操作就是可行的了。

记斐波那契数列 \(f\) 的普通生成函数为 \(F(x)\),根据定义式我们有 \(F(x)=\sum_{n\ge0}f_nx^n\)。变形得:

\[\begin{aligned} F(x)&=\sum_{n\ge0}f_nx^n\\ &=f_0x^0+f_1x^1+\sum_{n\ge2}f_nx^n\\ &=0+x+\sum_{n\ge2}(f_{n-1}+f_{n-2})x^n\\ &=0+x+x\sum_{n\ge1}f_{n}x^n+x^2\sum_{n\ge0}f_nx^n\\ &=0+x+x(F(x)-f_0x^0)+x^2F(x)\\ \end{aligned} \]

整理得 \((1-x-x^2)F(x)=x\),解得 \(F(x)=\dfrac{x}{1-x-x^2}\)。

我们已经推出了 \(F(x)\) 的一种形式,接下来要把它展开了。

考虑两个序列 \(a,b\) 的普通生成函数,分别记为为 \(F_a(x),F_b(x)\)。那么有 \(F_a(x)\pm F_b(x)=\sum_{n\ge0}(a_n\pm b_n)x^n\)。因此 \(F_a(x)\pm F_b(x)\) 是序列 \(\langle a_n\pm b_n\rangle\) 的普通生成函数。这个我们待会要用。

再考虑等比数列 \(\langle 1,d,d^2\ldots\rangle\) 的普通生成函数,记为 \(G(x)\)。那么有:

\[\begin{aligned} G(x)&=\sum_{n\ge0}d^nx^n\\ &=1+\sum_{n\ge1}d^nx^n\\ &=1+dx\sum_{n\ge0}d^nx^n\\ &=1+dxG(x) \end{aligned} \]

整理得 \((1-dx)G(x)=1\),解得 \(G(x)=\dfrac{1}{1-dx}\)。这个我们待会也要用。

令:

\[\dfrac{A}{1-ax}+\dfrac{B}{1-bx}=\dfrac{x}{1-x-x^2} \]

解得:

\[\begin{cases} A=\frac{1}{\sqrt{5}}\\ B=-\frac{1}{\sqrt{5}}\\ a=\frac{1+\sqrt{5}}{2}\\ b=\frac{1-\sqrt{5}}{2} \end{cases} \]

即:

\[\frac{1}{\sqrt{5}}\displaystyle\left(\dfrac{1}{1-\frac{1+\sqrt{5}}{2}x}-\dfrac{1}{1-\frac{1-\sqrt{5}}{2}x}\right)=\dfrac{x}{1-x-x^2} \]

联系上文推出的等比数列的展开式的形式,以及普通生成函数的基本运算知识,可以得到 \(F(x)\) 的另一种形式:

\[F(x)=\frac{x}{1-x-x^2}=\sum_{n\ge0}x^n\frac{1}{\sqrt{5}}\left(\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n\right) \]

即斐波那契数列 \(f_n\) 的通项公式为:

\[f_n=\frac{1}{\sqrt{5}}\left(\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n\right) \]

这个东西可以左右两半拆开,把 \(\dfrac{1}{\sqrt{5}}\) 提出来,两边分别用区间加等比数列维护。

虽然我们已经推出了 \(f_n\) 的通项公式,但式子中包含无理数,怎么处理呢?

定义 \(n\) 在膜 \(p\) 意义下的二次剩余为满足 \(x^2\equiv n\pmod p\) 的整数 \(x\)。那么我们只需要求出无理数的二次剩余就可以维护了。

这里,我们并不需要去学习如何求二次剩余。因为我们只需要知道 \(\dfrac{1}{\sqrt{5}}\) 这一个数的二次剩余,我们可以枚举一下,得到 \(383008016^2\equiv5\pmod{10^9+9}\)。其余求逆元等过程按下不表。

由于这个问题的特殊性,我们只需要维护区间加首项为 \(1\),公比固定的等比数列。区间维护 \(tag\) 表示当前区间加的等比数列的首项,显然两次操作可以合并。

code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18,mod=1e9+9;
const int A=276601605;
const int D[2]={691504013,308495997};
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int pw[2][300005],spw[2][300005];
int ask(int o,int l,int r){
	if(l==0)return spw[o][r];
	return (spw[o][r]-spw[o][l-1]+mod)%mod;
}
struct segtree{
	#define ls p<<1
	#define rs p<<1|1
	#define lson l,mid,ls
	#define rson mid+1,r,rs
	struct Node{
		int s[2],tag[2];
	}c[1200005];
	void pushup(int p){
		for(int o=0;o<2;o++)c[p].s[o]=(c[ls].s[o]+c[rs].s[o])%mod;
	}
	void pushdown(int l,int r,int p){
		int mid=(l+r)>>1;
		for(int o=0;o<2;o++){
			c[ls].s[o]=(c[ls].s[o]+c[p].tag[o]*ask(o,0,mid-l)%mod)%mod,c[rs].s[o]=(c[rs].s[o]+c[p].tag[o]*ask(o,mid+1-l,r-l)%mod)%mod;
			c[ls].tag[o]=(c[ls].tag[o]+c[p].tag[o])%mod,c[rs].tag[o]=(c[rs].tag[o]+c[p].tag[o]*pw[o][mid-l+1]%mod)%mod;
			c[p].tag[o]=0; 
		}
	}
	void build(int l,int r,int p){
		for(int o=0;o<2;o++)c[p].tag[o]=0;
		if(l==r){
			for(int o=0;o<2;o++)c[p].s[o]=0;
			return;
		}
		int mid=(l+r)>>1;
		build(lson),build(rson);
		pushup(p);
	}
	void update(int l,int r,int p,int L,int R){
		if(L<=l&&r<=R){
			for(int o=0;o<2;o++){
				c[p].s[o]=(c[p].s[o]+ask(o,l-L+1,r-L+1))%mod;
				c[p].tag[o]=(c[p].tag[o]+pw[o][l-L+1])%mod;
			}
			return;
		}
		int mid=(l+r)>>1;pushdown(l,r,p);
		if(L<=mid)update(lson,L,R);
		if(R>mid)update(rson,L,R);
		pushup(p);
	}
	int query(int l,int r,int p,int L,int R){
		if(L<=l&&r<=R)return (c[p].s[0]-c[p].s[1]+mod)%mod;
		int mid=(l+r)>>1,res=0;pushdown(l,r,p);
		if(L<=mid)res=(res+query(lson,L,R))%mod;
		if(R>mid)res=(res+query(rson,L,R))%mod;
		return res;
	}
	#undef ls
	#undef rs
	#undef lson
	#undef rson
}Tr;
int a[300005],s[300005];
signed main(){
	int n=read(),m=read();
	for(int o=0;o<2;o++){
		pw[o][0]=spw[o][0]=1;
		for(int i=1;i<=n;i++)pw[o][i]=pw[o][i-1]*D[o]%mod,spw[o][i]=(spw[o][i-1]+pw[o][i])%mod;
	}
	for(int i=1;i<=n;i++)a[i]=read(),s[i]=(s[i-1]+a[i])%mod;
	Tr.build(1,n,1);
	while(m--){
		int o=read(),l=read(),r=read();
		if(o==1)Tr.update(1,n,1,l,r);
		else printf("%lld\n",((s[r]-s[l-1]+mod)%mod+A*Tr.query(1,n,1,l,r)%mod)%mod);
	}
	return 0;
}

标签:right,frac,int,dfrac,sum,sqrt,Fibonacci,DZY,CF446C
From: https://www.cnblogs.com/xx019/p/17417262.html

相关文章

  • 【CF446C】DZY Loves Fibonacci Numbers(线段树)
    Description给定一个序列,资瓷区间加上一个斐波那契数列,区间求和。Solution有一个性质:fib[a+b]=fib[a−1]×fib[b]+fib[a]×fib[b+1]fib[a+......
  • codeforces#FF DIV2C题DZY Loves Sequences(DP)
    题目地址:http://codeforces.com/contest/447/problem/CC.DZYLovesSequencestimelimitpertestmemorylimitpertestinputoutputa,consistingof nai, ai + 1, .........
  • HDU 1588 Gauss Fibonacci(矩阵快速幂)
    题目地址:HDU1588用于构造斐波那契的矩阵为1,11,0设这个矩阵为A。sum=f(b)+f(k+b)+f(2*k+b)+f(3*k+b)+........+f((n-1)*k+b)<=>sum=A^b+A^(k+b)+A^(2*k+b)+A^(3*k+b)+........+A^((n-1)*k+b)<=>sum=A^b+A^b*(A^k+A^2*k+A^3*k+.......+A^((n-1)*k))(1)设矩阵B为A^k;那么(1......
  • HDU 3306 Another kind of Fibonacci(矩阵快速幂)
    题目地址:HDU3306没什么智商的题目,只要把构造矩阵硬算出来就行。代码如下:#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<stdlib.h>#include<math.h>#include<ctype.h>#include<queue>#include<......
  • 6-1 使用函数输出指定范围内Fibonacci数的个数
    本题要求实现一个计算Fibonacci数的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m<n≤100000)之间的所有Fibonacci数的数目。所谓Fibonacci数列就是满足任一项数字是......
  • DZY Loves Colors
    DZYLovesColors题面翻译有一个\(n\)个元素组成的序列,每个元素有两个属性:颜色\(c_i\)和权值\(w_i\)。\(c_i\)初始为\(i\),\(w_i\)初始为\(0\)。\(m\)次操作,操......
  • UVA-12333 Fibonacci的复仇 题解答案代码 算法竞赛入门经典第二版
    ​​GitHub-jzplp/aoapc-UVA-Answer:算法竞赛入门经典例题和习题答案刘汝佳第二版​​算法竞赛入门经典书中给出了大数类的算法,直接照抄即可。我的做题过程:1.照着书......
  • Codeforces Round #254 (Div. 1) C - DZY Loves Colors 线段树|lazytag维护区间加
    开一个变量维护同一个区间内颜色是否相同,而且显然要用lazytag了递归到颜色相同的区间时就可以直接打标记然后对于标记,维护的就是常规区间加的部分(最开始没写lazy,wa6,没明......
  • Fibonacci 第 n 项
     #include<iostream>#include<cmath>#include<algorithm>usingnamespacestd;#defineN2intmod;#defineintlonglongstructmatrix{ ......
  • HDOJ1021 Fibonacci Again
    题目链接:​​http://acm.hdu.edu.cn/showproblem.php?pid=1021​​这个题最坑的莫过于范围了,开始用long,测试了下,发现很快就超范围了。然后想着使用大数,考虑到时间的限制,再次......