题目大意:给出一个长度为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]);
}

[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II的更多相关文章

  1. [Codeforces 316E3]Summer Homework(线段树+斐波那契数列)

    [Codeforces 316E3]Summer Homework(线段树+斐波那契数列) 顺便安利一下这个博客,给了我很大启发(https://gaisaiyuno.github.io/) 题面 有 ...

  2. Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列

    C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...

  3. 【CF446C】DZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)

    Description ​ 看题戳我 给你一个序列,要求支持区间加斐波那契数列和区间求和.\(~n \leq 3 \times 10 ^ 5, ~fib_1 = fib_2 = 1~\). Solut ...

  4. hdu 4983 线段树+斐波那契数

    http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 从l到r区间 ...

  5. CF633H Fibonacci-ish II 莫队、线段树、矩阵乘法

    传送门 这题除了暴力踩标程和正解卡常数以外是道很好的题目 首先看到我们要求的东西与\(Fibonacci\)有关,考虑矩阵乘法进行维护.又看到\(n \leq 30000\),这告诉我们正解算法其实比 ...

  6. SPOJ DQUERY - D-query (莫队算法|主席树|离线树状数组)

    DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query ...

  7. Python开发【算法】:斐波那契数列两种时间复杂度

    斐波那契数列 概述: 斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1, ...

  8. 算法笔记_001:斐波那契数的多种解法(Java)

    本篇文章解决的问题来源于算法设计与分析课程的课堂作业,主要是运用多种方法来计算斐波那契数.具体问题及解法如下: 一.问题1: 问题描述:利用迭代算法寻找不超过编程环境能够支持的最大整数的斐波那契数是第 ...

  9. hdu 4099 字典树 + 斐波那契

    题意:       给你一个串(最长40位)问你这个串是斐波那契F(n)  n <= 99999中的那个数的前缀,如果存在多个输出最小的n否则输出-1. 思路:       给的串最长40位,那 ...

随机推荐

  1. Druid 架构

    本篇译自 Druid 项目白皮书部分内容( https://github.com/apache/incubator-druid/tree/master/publications/whitepaper/ ...

  2. python版GetTickCount()

    time.clock() return the current processor time as a floating point number expressed in seconds. 即返回一 ...

  3. ORACLE数据库创建动态表

    最近公司一个项目代码里的定时任务无法执行,查验代码良久,奈何代码过于老旧,开发人员换了一茬又一茬,现在都无法理清,故无奈只好到数据库里重新写存过,配置定时任务. 在写存过时,由于检测及安全性能要求,需 ...

  4. 洛谷—— P2562 [AHOI2002]Kitty猫基因编码

    P2562 [AHOI2002]Kitty猫基因编码 题目描述 小可可选修了基础生物基因学.教授告诉大家 Super Samuel 星球上 Kitty猫的基因的长度都是 2 的正整数次幂 ), 全是由 ...

  5. Sqli-labs less 2

    Less-2 将'(单引号)添加到数字中. 我们又得到了一个Mysql返回的错误,提示我们语法错误. You have an error in your SQL syntax; check the m ...

  6. LAMP搭建Discuz论坛

    搭建Discuz论坛 1.  准备LAMP环境 LAMP是Linux,Apache,MySql和PHP的缩写,是Discuz论坛系统依赖的基础运行环境 1.安装Apache2 Ubuntu需要安装Ap ...

  7. 1. ECMAScript 6 简介--ES6

    1. ECMAScript 和 JavaScript 的关系 国际标准化组织ECMA 制定了语言 ECMAScript, 该标准针对 Javascript 语言制定, 不叫Javascript 原因有 ...

  8. [SDOI2005]反素数ant

    题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6 ...

  9. JZYZOJ1457 [NOIP2016]换教室 期望dp 动态规划 floyd算法 最短路

    http://172.20.6.3/Problem_Show.asp?id=1457 我不知道为什么我倒着推期望只有80分,所以我妥协了,我对着题解写了个正的,我有罪. #include<cst ...

  10. Luogu P3960 列队 线段树

    题面 线段树入门题. 我们考虑线段树来维护这个矩阵. 首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学.再定n+1棵线段树前n棵线段树维护 ...