[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II
题目大意:给出一个长度为n的数列a。
对于一个询问lj和rj。将a[lj]到a[rj]从小到大排序后并去重。设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk。当中F为斐波那契数列。F1=F2=1。对每一个询问输出答案模m。
区间查询离线 用莫队算法
开棵权值线段树,然后用斐波那契的性质update
F(n+m)=F(n+1)*F(m)+F(n)*F(m-1);
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;inline char nc()
{static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;
}inline void read(int &x)
{char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}int P;
int sx[30005];
int icnt;inline int Bin(int x){return lower_bound(sx+1,sx+icnt+1,x)-sx;
}struct SEGTREE{struct node{int k;int fk,fk_1;int a1,a2;friend node operator + (node &A,node &B){if (!A.k) return B;if (!B.k) return A;node ret;ret.k=A.k+B.k;(ret.fk=(A.fk+A.fk_1)*B.fk+A.fk*B.fk_1)%=P;(ret.fk_1=A.fk*B.fk+A.fk_1*B.fk_1)%=P;ret.a1=A.a1;(ret.a1+=A.fk*B.a2+A.fk_1*B.a1)%=P;ret.a2=A.a2;(ret.a2+=(A.fk+A.fk_1)*B.a2+A.fk*B.a1)%=P;return ret;}};node T[120005];int cnt[120005];int M,TH;inline void Build(int n){for (M=1,TH=0;M<n+2;M<<=1,TH++);}inline int Query(){return T[1].a1;}inline void Change(int s,int r){s+=M;if (r==1){cnt[s]++;if (cnt[s]==1){T[s].k=1;T[s].fk=1;T[s].fk_1=0;(T[s].a1=sx[s-M])%=P;(T[s].a2=sx[s-M])%=P;while (s>>=1)T[s]=T[s<<1]+T[s<<1|1];}}else if (r==-1){cnt[s]--;if (cnt[s]==0){T[s].k=0;T[s].fk=0;T[s].fk_1=0;T[s].a1=0;T[s].a2=0;while (s>>=1)T[s]=T[s<<1]+T[s<<1|1];}}}
}SEG;int n,Q,B;
int a[30005],ans[30005];struct event{int x,y,lpos;int idx;bool operator < (const event &B) const{return lpos==B.lpos?y<B.y:lpos<B.lpos;}
}eve[30005];inline void Mos()
{int l=1,r=0;for (int i=1;i<=Q;i++){while (r<eve[i].y) SEG.Change(Bin(a[++r]),1);while (r>eve[i].y) SEG.Change(Bin(a[r--]),-1);while (l<eve[i].x) SEG.Change(Bin(a[l++]),-1);while (l>eve[i].x) SEG.Change(Bin(a[--l]),1);ans[eve[i].idx]=SEG.Query();}
}int main()
{freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(P); B=sqrt(n);for (int i=1;i<=n;i++)read(a[i]),sx[++icnt]=a[i];sort(sx+1,sx+icnt+1);icnt=unique(sx+1,sx+icnt+1)-sx-1;SEG.Build(icnt);read(Q);for (int i=1;i<=Q;i++){read(eve[i].x); read(eve[i].y);eve[i].lpos=(eve[i].x-1)/B+1; eve[i].idx=i;}sort(eve+1,eve+Q+1);Mos();for (int i=1;i<=Q;i++)printf("%d\n",ans[i]);return 0;
}
然而出题人太奇妙,这样的做法常数极大,还是暴力短小精悍
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e4+5;
pair<int,int> a[maxn];
int ans[maxn],step[maxn],f[maxn],l[maxn],r[maxn],last[maxn];int main()
{freopen("t.in","r",stdin);freopen("t1.out","w",stdout);int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i].first),a[i].second=i;sort(a+1,a+1+n);f[0]=1,f[1]=1;for(int i=2;i<=n;i++)f[i]=(f[i-1]+f[i-2])%m;int q;scanf("%d",&q);for(int i=1;i<=q;i++){scanf("%d%d",&l[i],&r[i]);last[i]=-1;}for(int i=1;i<=n;i++){int d = a[i].first % m;for(int j=1;j<=q;j++){if(a[i].second<l[j]||a[i].second>r[j])continue;if(a[i].first==last[j])continue;ans[j]=(ans[j]+f[step[j]++]*d)%m;last[j]=a[i].first;}}for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
}
转载于:https://www.cnblogs.com/clnchanpin/p/7279076.html
[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II相关推荐
- 算法 | 详解斐波那契数列问题
14天阅读挑战赛 本篇是学习了<趣学算法(第2版)> 第一章之后总结的. 上一篇讲到了等比数列求和问题,求Sn=1+2+22+23+...+263=?S_n = 1 + 2 + 2^2 + ...
- 算法之矩阵计算斐波那契数列
算法之矩阵计算斐波那契数列 本节内容 斐波那契介绍 普通方式求解斐波那契 矩阵概念 矩阵求幂 矩阵求解斐波那契 1.斐波那契介绍 斐波那契数列有关十分明显的特点,那是:前面相邻两项之和,构成了后一项. ...
- 查找算法之三:斐波那契查找(黄金分割法)
斐波那契查找 思路分析 代码实现 思路分析 FibonacciSearch(也叫黄金分割法)的思路分析: ==>实际上,这也是一个基于二分查找(也就是折半查找)的查找算法.只是在计算mid 的值 ...
- 算法导论之斐波那契堆
斐波那契堆,和二项堆类似,也是由一组最小堆有序的树构成.注意区别,不是二项树,是有根而无序的树.导论中,斐波那契堆只是具有理论上的意义,是以平摊分析为指导思想来设计的数据结构,主要是渐进时间界比二项堆 ...
- hdu 4099 字典树 + 斐波那契
题意: 给你一个串(最长40位)问你这个串是斐波那契F(n) n <= 99999中的那个数的前缀,如果存在多个输出最小的n否则输出-1. 思路: 给的串最长40位,那 ...
- 算法笔记_001:斐波那契数的多种解法(Java)
本篇文章解决的问题来源于算法设计与分析课程的课堂作业,主要是运用多种方法来计算斐波那契数.具体问题及解法如下: 一.问题1: 问题描述:利用迭代算法寻找不超过编程环境能够支持的最大整数的斐波那契数是第 ...
- 【js算法】js斐波那契数列的多种算法
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列" ...
- 【使用递归玩通关汉诺塔游戏】算法01-递归(斐波那契数列、汉罗塔问题)-java实现
递归 定义:在一个方法(函数)的内部调用该方法(函数)本身的编程方式 简而言之就是 "自己调自己" 在玩游戏之前让我们先对递归有一个简单的了解吧! 5.1 递归简介 递归必须有一个 ...
- 【算法编程】斐波那契数列
题目来源:牛客网剑指offer 题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.n<=39 C++:5ms 476k #include <iostr ...
- 递归、尾递归、迭代算法【在 斐波拉契数列】上的实现
/* 递归: [逆序]从未知点推到已知点,[顺序]代入已知点结果,从已知点带入并计算到未知点,最终到终点 尾递归: 从起点开始,依顺序计算结果,并无限靠近最终目标点 迭代: 从 ...
最新文章
- 前端学习(1996)vue之电商管理系统电商系统之美化步骤条
- 关于RDLC使用导出PDF文件时,中文乱码解决方案
- 根号x_【深情攻X自卑受】糖与盐by根号三
- 建立自己的voc数据集_Mac上 制作自己的VOC数据集
- Android 处理软键盘遮挡问题
- amos看拟合度在哪里看_AMOS分析技术:结构方程模型的拟合度评价指标
- 基于MATLAB的人眼开度疲劳检测识别
- FFmpeg 以及帧率的解释
- 使用jwplayer插件播放视频
- 面包机面包/蛋糕配方
- 《Android编程权威指南(第三版)》第五章挑战练习Demo
- 数理方程——达朗贝尔公式
- [生存志] 第59节 仲尼弟子座次
- 用数组存储三个学生对象,并遍历数组
- 获取 COM 服务器进程 ID 的 3 种方法
- 10.28字符串加密等
- iOS:UIScrollView、UITableView、UICollectionView顶部空白问题
- 卡到不行的电脑升级?换硬盘,加内存条, 戴尔 Inspiron 5459 也挺好使
- Akka源码分析-FSM
- 多目标优化算法:多目标跳跃蜘蛛优化算法MOJSOA(提供Matlab代码)