H. Fibonacci-ish II

题目连接:

http://codeforces.com/contest/633/problem/H

Description

Yash is finally tired of computing the length of the longest Fibonacci-ish sequence. He now plays around with more complex things such as Fibonacci-ish potentials.

Fibonacci-ish potential of an array ai is computed as follows:

Remove all elements j if there exists i < j such that ai = aj.

Sort the remaining elements in ascending order, i.e. a1 < a2 < ... < an.

Compute the potential as P(a) = a1·F1 + a2·F2 + ... + an·Fn, where Fi is the i-th Fibonacci number (see notes for clarification).

You are given an array ai of length n and q ranges from lj to rj. For each range j you have to compute the Fibonacci-ish potential of the array bi, composed using all elements of ai from lj to rj inclusive. Find these potentials modulo m.

Input

The first line of the input contains integers of n and m (1 ≤ n, m ≤ 30 000) — the length of the initial array and the modulo, respectively.

The next line contains n integers ai (0 ≤ ai ≤ 109) — elements of the array.

Then follow the number of ranges q (1 ≤ q ≤ 30 000).

Last q lines contain pairs of indices li and ri (1 ≤ li ≤ ri ≤ n) — ranges to compute Fibonacci-ish potentials.

Output

Print q lines, i-th of them must contain the Fibonacci-ish potential of the i-th range modulo m.

Sample Input

5 10

2 1 2 1 2

2

2 4

4 5

Sample Output

3

3

Hint

题意

给你n个数,然后有q次询问

每次询问给你l,r区间

你首先得把l,r区间的数全部拿出来,从小到大排序,然后再去重

然后答案就等于ans = f[1]*a[1]+f[2]*a[2]....+f[n]*a[n]

其中f[i]是第i个fib数

要求答案mod m

题解:

现在出题人总喜欢艹一些大新闻出来

出一些复杂度迷的题目

这道题正解是莫队+奇怪的东西去维护

但是由于常数太大了,还没有大力出奇迹的暴力跑得快……

你说肿么办?

正解如下:

莫队去处理询问,然后线段树去处理答案

线段树怎么处理呢?

这里比较麻烦处理的是push_up

push_up你可以用矩阵去写。

每个点维护两个矩阵,[1][2]是答案的矩阵,[2][2]是fib的矩阵

a[i][1][2] = a[i*2][1][2] + a[i*2+1][1][2] * a[i*2][2][2]

a[i][2][2] = a[i*2][2][2]*a[i*2+1][2][2]

乘号是矩阵乘法

当然,用数学方法也可以

f(k+1)*(a1*f(i)+a2*f(i+1)+...)+f(k)*(a1*(f(i-1))+a2*f(i)....) = a1*f(i+k)+a2*f(i+k+1).....

大暴力代码

#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()
{
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]);
}

莫队

#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e4+5;
int a[maxn],pos[maxn],q,n,m,d[maxn];
int fib[maxn][2];
map<int,int> H;
vector<int> V;
long long Ans[maxn];
int cnt[maxn];
typedef int SgTreeDataType;
struct treenode
{
int L , R ;
SgTreeDataType sum1,sum2,siz;
void update(SgTreeDataType v)
{
siz = v;
sum1 = sum2 = v*d[L]%m;
}
}; treenode tree[maxn*4]; inline void push_down(int o)
{ } inline void push_up(int o)
{
tree[o].siz = tree[2*o].siz + tree[2*o+1].siz;
tree[o].sum1 = (tree[2*o].sum1+fib[tree[2*o].siz][0]*tree[o*2+1].sum1+fib[tree[2*o].siz][1]*tree[o*2+1].sum2)%m;
tree[o].sum2 = (tree[2*o].sum2+fib[tree[2*o].siz+1][0]*tree[o*2+1].sum1+fib[tree[2*o].siz+1][1]*tree[o*2+1].sum2)%m;
} inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].sum1 = tree[o].sum2 = tree[o].siz = 0;
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
}
} inline void update(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].update(v);
else
{
push_down(o);
int mid = (L+R)>>1;
if (QL <= mid) update(QL,QR,v,o*2);
if (QR > mid) update(QL,QR,v,o*2+1);
push_up(o);
}
}
struct query
{
int l,r,id;
}Q[maxn];
bool cmp(query a,query b)
{
if(pos[a.l]==pos[b.l])
return a.r<b.r;
return pos[a.l]<pos[b.l];
}
void Updata(int x)
{
int p = H[a[x]];
cnt[p]++;
if(cnt[p]==1)
update(p,p,1,1);
}
void Delete(int x)
{
int p = H[a[x]];
cnt[p]--;
if(cnt[p]==0)
update(p,p,0,1);
}
int main()
{
scanf("%d%d",&n,&m);
int sz =ceil(sqrt(1.0*n));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
V.push_back(a[i]);
pos[i]=(i-1)/sz;
} sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());
for(int i=0;i<V.size();i++)
{
H[V[i]]=i+1;
d[i+1]=V[i]%m;
} fib[0][0]=1%m,fib[1][1]=1%m;
for(int i=2;i<=n;i++)
{
fib[i][0]=(fib[i-1][0]+fib[i-2][0])%m;
fib[i][1]=(fib[i-1][1]+fib[i-2][1])%m;
}
build_tree(1,n,1);
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].id = i;
}
sort(Q+1,Q+1+q,cmp);
int l = 1,r = 0;
int ans=0;
for(int i=1;i<=q;i++)
{
int id = Q[i].id;
while(r<Q[i].r)
{
r++;
Updata(r);
}
while(l>Q[i].l)
{
l--;
Updata(l);
}
while(r>Q[i].r)
{
Delete(r);
r--;
}
while(l<Q[i].l)
{
Delete(l);
l++;
}
Ans[id]=tree[1].sum1;
}
for(int i=1;i<=q;i++)
printf("%lld\n",Ans[i]);
}

Manthan, Codefest 16 H. Fibonacci-ish II 大力出奇迹 莫队 线段树 矩阵的更多相关文章

  1. 【CF633H】Fibonacci-ish II 莫队+线段树

    [CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...

  2. CF633H Fibonacci-ish II(莫队+线段树)

    温馨提示:本题十分卡常数,我手动开O2才过的.而数据范围不伦不类的n<=30000,常数小的O(n2)居然比O(n√nlogn)跑得快…… 考虑插进去一个元素对答案产生的影响.原本数列为Σa[i ...

  3. Manthan, Codefest 16

    暴力 A - Ebony and Ivory import java.util.*; import java.io.*; public class Main { public static void ...

  4. CF Manthan, Codefest 16 G. Yash And Trees 线段树+bitset

    题目链接:http://codeforces.com/problemset/problem/633/G 大意是一棵树两种操作,第一种是某一节点子树所有值+v,第二种问子树中节点模m出现了多少种m以内的 ...

  5. 牛客小白月赛12 H 华华和月月种树 (离线dfs序+线段树)

    链接:https://ac.nowcoder.com/acm/contest/392/H 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K,其他语言2621 ...

  6. Codeforces 446C - DZY Loves Fibonacci Numbers(斐波那契数列+线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 你可能会疑惑我为什么要写 *2400 的题的题解 首先一个很明显的想法是,看到斐波那契数列和 \(10^9+9\) 就想到通项公式,\(F ...

  7. Manthan, Codefest 16 D. Fibonacci-ish

    D. Fibonacci-ish time limit per test 3 seconds memory limit per test 512 megabytes input standard in ...

  8. Manthan, Codefest 16 D. Fibonacci-ish 暴力

    D. Fibonacci-ish 题目连接: http://www.codeforces.com/contest/633/problem/D Description Yash has recently ...

  9. CF #Manthan, Codefest 16 C. Spy Syndrome 2 Trie

    题目链接:http://codeforces.com/problemset/problem/633/C 大意就是给个字典和一个字符串,求一个用字典中的单词恰好构成字符串的匹配. 比赛的时候是用AC自动 ...

随机推荐

  1. Python学习笔记 - day14 - Celery异步任务

    Celery概述 关于celery的定义,首先来看官方网站: Celery(芹菜) 是一个简单.灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具. 简单来看,是一个基于pyt ...

  2. linux编程之共享内存

    linux 进程间通信(IPC)包括3种机制:消息队列.信号量.共享内存.消息队列和信号量均是内核空间的系统对象,经由它们 的数据需要在内核和用户空间进行额外的数据拷贝:而共享内存和访问它的所有应用程 ...

  3. 【转】C++多继承的细节

    这几天写的程序应用到多继承. 以前对多继承的概念非常清晰,可是很久没用就有点模糊了.重新研究一下,“刷新”下记忆. 假设我们有下面的代码: #include <stdio.h> class ...

  4. python基础===类的私有属性(伪私有)

    说在前面的一点: python明明有私有的定义方法就是在变量或者方法的面前加上双下滑线__,这个实际上是python的伪私有.只是一种程序员约定俗称的规定,加了就表示私有变量,但是你如果要在外部调用的 ...

  5. mongodb 学习笔记 3 --- 查询

    在mongodb的查询中可以通过使用如下操作符进行深度查询 1.条件操作符 $gt  $gte : >  >=   {"age":{"$gt":18 ...

  6. 【2017 Multi-University Training Contest - Team 1】小结

    啊人生第一次打多校被虐 紧随yql的脚步做题. 1001: 可以发现我们平时表示的数都是$x*log_{10}{10}$,所以类似于做一个换底公式就可以了. -1是一个烟雾弹,因为小学生都知道2^n不 ...

  7. 网站服务器压力Web性能测试(3):http_load:测试web服务器的吞吐量与负载

    1.http_load是国外一个博主写的一个基于Linux的性能测工具,小巧轻便,解压缩后不到100k,下载安装方法: wget https://acme.com/software/http_load ...

  8. 关闭自动弹出照片自动弹出iTunes以及关闭手机照片流

    关闭自动弹出照片自动弹出iTunes以及关闭手机照片流 如何阻止iPhone连接Mac后自动弹出照片? 时间:2015/6/18 17:07:15来源:本站原创作者:Chenjh我要评论 很多新 iP ...

  9. 微信小程序使用canvas绘制图片的注意事项

    1.单位换算问题,canvas的尺寸单位是px,所以单位需要做个换算,可以通过wx.getSystemInfo获取屏幕宽高(单位是px),微信小程序无论什么机型,屏幕宽度都是750rpx,因此可以做个 ...

  10. 如何在datepicker滚动完毕后触发事件去获得日期

    本来以为这件事情应该需要借助datepicker的委托来处理的,但是并没有找到此空间的委托. 其实最最简单的做法就是在IB中将次控件connect到一个Action上. 经过测试,当datepicke ...