CF633H Fibonacci-ish II
题目描述
题解:
坑题搞了三天。
莫队+线段树。
还有一些和斐波那契数列有关的性质。
首先答案是$a_1f_1+a_2f_2+…+a_nf_n$,
考虑插进去一个元素对答案产生的影响。
比如插进去一个$a_0$,插进去之后会排到第$k$位。
那么答案是$a_1f_1+a_2f_2+…+a_0f_k+a_kf_{k+1}+…+a_nf_{n+1}$,
等于$ans0+a_0f_k+a_kf_{k-1}+…+a_nf_{n-1}$。
所以单点插入,区间加斐波那契数?
不可能的。
考虑用矩阵推出斐波那契数列。
其实不需要矩阵快速幂,存当前$a_i*f_i$和前一个数$a_i*f_{i-1}$即可,
比如我们存的是$(a,b)$,那么有
$(a,b)->(a+b,a)->(2a+b,a+b)->(3a+2b,2a+b)->(5a+3b,3a+2b)->……$
系数都是斐波那契数。
向前转移同理
$(a,b)->(b,a-b)->(a-b,-a+2b)->(-a+2b,2a-3b)->……$
这个系数可以和斐波那契数列一起求,转移也很好推。
线段树单点插入时要一起搞事情,取模要少取,不然会$T$的很惨。
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N = 30050; template<typename T> inline void read(T&x) {T f = 1,c = 0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}x = f*c; } int n,qq,w[N],to[N],m=0,B=170; int MOD,f[N],g[N],ans[N]; void Mod(int&x){if(x>=MOD)x-=MOD;} void init() {if(MOD==1)return ;f[1]=f[2]=1;for(int i=3;i<=n+1;i++)Mod(f[i]=f[i-1]+f[i-2]);g[1]=1,g[2]=MOD-1;for(int i=3;i<=n+1;i++)Mod(g[i]=g[i-2]-g[i-1]+MOD); } struct Pair {int x,y;Pair(){}Pair(int x,int y):x(x),y(y){} }p[N]; bool cmp(Pair a,Pair b){return a.x<b.x;} struct Q {int l,r,id;Q(){}Q(int l,int r,int i):l(l),r(r),id(i){} }q[N]; bool CMP(Q a,Q b){return (a.l/B)==(b.l/B)?(a.r<b.r):(a.l<b.l);} struct segtree {int siz[N<<2],tag[N<<2];int c[N<<2][2];void update(int u){siz[u] = siz[u<<1]+siz[u<<1|1];Mod(c[u][0] = c[u<<1][0]+c[u<<1|1][0]);Mod(c[u][1] = c[u<<1][1]+c[u<<1|1][1]);}void add(int u,int k){tag[u] += k;int a = c[u][0],b = c[u][1];if(k>0){(c[u][0] = a*f[k+1]+b*f[k])%=MOD;(c[u][1] = a*f[k]+b*f[k-1])%=MOD;}else if(k<0){k = -k;(c[u][0] = a*g[k-1]+b*g[k])%=MOD;(c[u][1] = a*g[k]+b*g[k+1])%=MOD;}}void pushdown(int u){if(tag[u]){add(u<<1,tag[u]);add(u<<1|1,tag[u]);tag[u] = 0;}}void insert(int l,int r,int u,int qx,int k,int d){if(l==r){if(k==-1)c[u][0]=c[u][1]=0,siz[u] = 0;else c[u][0] = f[k]*to[l]%MOD,c[u][1] = f[k-1]*to[l]%MOD,siz[u] = 1;return ;}pushdown(u);int mid = (l+r)>>1;if(qx<=mid)insert(l,mid,u<<1,qx,k,d),add(u<<1|1,d);else insert(mid+1,r,u<<1|1,qx,k+(k!=-1)*siz[u<<1],d);update(u);} }tr; int vis[N]; inline void push(int x) {if(!x)return ;if(!vis[x])tr.insert(1,m,1,x,1,1);vis[x]++; } inline void pull(int x) {if(!x)return ;vis[x]--;if(!vis[x])tr.insert(1,m,1,x,-1,-1); } int main() { // freopen("tt.in","r",stdin); read(n),read(MOD);init();for(int a,i=1;i<=n;i++)read(a),p[i]=Pair(a,i);sort(p+1,p+1+n,cmp);for(int las = 0x3f3f3f3f,i=1;i<=n;i++){if(las != p[i].x){las = p[i].x;to[++m] = las%MOD;}w[p[i].y] = m;}read(qq);for(int l,r,i=1;i<=qq;i++){read(l),read(r);q[i]=Q(l,r,i);}sort(q+1,q+1+qq,CMP);int L = 0,R = 0;for(int i=1;i<=qq;i++){while(R<q[i].r)push(w[++R]);while(R>q[i].r)pull(w[R--]);while(L<q[i].l)pull(w[L++]);while(L>q[i].l)push(w[--L]);ans[q[i].id]=tr.c[1][0];}for(int i=1;i<=qq;i++)printf("%d\n",ans[i]);return 0; }
转载于:https://www.cnblogs.com/LiGuanlin1124/p/10712874.html
CF633H Fibonacci-ish II相关推荐
- 递推--Fibonacci数列 II
描述 众所周知,Fibonacci数列是一个著名数列.它的定义是: 本题要求采用第二种方法:递推. 输入描述 每行一个整数 i ,表示 Fibonacci 数列的第i项. i ≤ 100000 对比前 ...
- 斐波那契序列 Fibonacci
[定理1] 标准Fibonacci序列(即第0项为0,第1项为1的序列)当N大于1时,一定有f(N)和f(N-1)互质 其实,结合"互质"的定义,和一个很经典的算法就可以轻松证明 ...
- UVA11161 Help My Brother (II)【大数+递推】
A Fibonacci sequence is calculated by adding the previous two members of the sequence, with the firs ...
- 面试时最经常被问到的问题(Frenquently asked interview questions)(II)
面试时最经常被问到的问题(Frenquently asked interview questions)(II) 面试时最经常被问到的问题(Frenquently asked interview que ...
- 面试时最经常被问到的问题II
今天看到一篇非常不错的文章,拿来 转帖-- 面试时最经常被问到的问题(Frenquently asked interview questions)(II) 面试时最经常被问到的问题(Frenquent ...
- 斐波那契数列在计算机的应用,斐波那契(Fibonacci)数列的几种计算机解法
题目:斐波那契数列,又称黄金分割数列(F(n+1)/F(n)的极限是1:1.618,即黄金分割率),指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.--.在数学上,斐波纳契数列以如下 ...
- HDUOJ 6755 Fibonacci Sum
HDUOJ 6755 Fibonacci Sum 题目链接 Problem Description The Fibonacci numbers are defined as below: Given ...
- Fibonacci数列的java实现
关于Fibonacci应该都比较熟悉,0,1,1,2,3..... 基本公式为f(n) = f(n-1) + f(n-2); f(0) = 0; f(1) =1; 方法1:可以运用迭代的方法实现: p ...
- ZOJ 2723 Semi-Prime ||ZOJ 2060 Fibonacci Again 水水水!
两题水题: 1.如果一个数能被分解为两个素数的乘积,则称为Semi-Prime,给你一个数,让你判断是不是Semi-Prime数. 2.定义F(0) = 7, F(1) = 11, F(n) = F( ...
- 剑指offer:面试题32 - II. 从上到下打印二叉树 II
题目:从上到下打印二叉树 II 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ ...
最新文章
- RNN和LSTM的正向/前向传播-图示公式和代码
- r语言和python-R语言和Python哪个适合生物信息学?
- 车联网行业No.1元征科技的云端架构实现
- 什么是 Round trip time RTT
- 移动开发技术新趋向(三)
- pip命令提示unknow or unsupported command install解决方法
- 运行差分灰狼时出现 关于“索引超出数组元素的数目(0)和矩阵维度问题以及图例的问题”的解决办法
- mysql语句中变量 c#_C#基础知识-您的第一个C#程序,类型和变量以及流控制语句...
- s7填表指令att_第五章 S7-200 指令系统.ppt
- 用turtle画中国象棋棋盘
- 中英文对照 —— 软件与病毒、电子与硬件
- python屏幕录像专家_可以推荐一款电脑录屏软件吗?
- 阜阳智慧城市建设居全国地市级城市第11位
- Linux C 下的socket网络编程
- 微信步数修改.html,把微信步数修改到小
- vue数据层思路_vue层级关系的数据管理
- java 判断是不是昨天、今天、明天
- 竑观资产合伙人孙霄汉:区块链经济三个系统的X关系
- 聊聊消息中心的设计与实现逻辑
- 基于javaweb+SSM的校园外卖点餐系统(java+SSM+JSP+maven+mysql)
热门文章
- 声音和视频在计算机的格式,格式工厂完成音频和视频合并
- xshell的快捷复制粘贴设置(*)
- 【linux】rpm和src.rpm、rpm和noarch.rpm的区别
- python pygame 游戏实战:Maze 迷宫生成,显示和游戏(附全部代码)
- windows10桌面壁纸的储存地址在哪里
- python设置计算题_python tkinter做的生成计算题的GUI
- 使用D3.js进行Neo4j数据的前端展示
- 去年我国软件业收入4.3万亿元 同比增长16.6%
- Jenkins配置邮件, Extended E-mail Notification, 破解管理员密码
- Elk-Metricbeat配置Nginx的日志分析 (Metricbeat-part2)