小红帽的画笔(NOIP模拟赛Round 7)
又到了神奇的模拟赛时间~
真是丧~
好吧我们来看看题目
小红帽是Pop star上最著名的人类画家,她可以将任何画出的东西变成真实的物品。赋予她这样神奇能力的正是她手上的画笔。
小红帽每次作画时,都需要用到她的调色盘,我们把每个自然数都对应一种颜色,那么小红帽的调色盘就可以看成是一个斐波那契数列(数列第1、2项都为1),小红帽每次需要一种颜色时,她都会用画笔蘸取一段区间,得到的颜色就是区间里所有的数之和。
受到秋之国人民的邀请,小红帽要为他们画一个夏天。小红帽要进行n次取色,给出每次蘸取的区间[l,r],作为小C委派来进行记录的你需要输出每次小红帽得到的颜色,答案对mod取模。
【数据范围】
对于10%的数据,n<=100,l,r<=10^4;
对于30%的数据,l,r<=10^7;
对于90%的数据,mod<=10^9;
对于100%的数据,0<=n<=1000,1<=l<=r<=10^18,0<mod<=10^18。
————————————————我是分割线————————————————————
很显然,这道题目就是求斐波那契数列前r项的前缀和减去前l-1项的前缀和,普通的DP都可以做到求斐波那契数列,但是很显然10^18我们就会T
在此我们讲讲矩阵乘法
矩阵乘法,顾名思义,就是2个矩阵相乘。具体如下

所以呢我们如果要算斐波那契数列的第N项只需要将图中的
矩阵自乘n-2次,再乘第一个矩阵,得到的矩阵的第一个数就是答案
那么我们又怎样求前缀和呢?
在此有两种方法供参考
TOP1:找规律
我们假设a,b为斐波那契数列的第一项和第二项
那么我们很显然就可以递推出后面的几项

那么这有什么规律呢?
很快就发现了规律
a=a+b-b;a+b=a+2b-b;2a+2b=2a+3b-b;3a+4b=3a+5b-b.....
所以我们只需要求num[r+2]-1-(num[l-1+r]-1)=num[r+2]-num[l-1]即可啦
TOP2:构造矩阵
显然我们知道我们要保留答案矩阵的前面2个数,而我们想办法构造出第三个数,用于计算前缀和。这样将这个矩阵自乘n-2次,输出第三个数就好啦。
然后我们会想到我们的前缀和就是sum[i]=sum[i-1]+num[i];
然后就会构造出这个矩阵啦
———————————————我是分割线—————————————————
那么我们还看到一个问题,如何处理mod?
我们知道如果mod为10^18
那么一次乘法操作的数会达到10^36
如果是这样我们就需要做高精除+高精乘了。
但是有没有更快的方法?
首先我们知道如果在加法中进行取余,结果不改变。
所以我们将乘法转变为加法
这样速度虽然慢了点,却不会爆long long
然后这道题就愉快解决啦!
下面贴代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
struct matrix{
unsigned long long mat[][];
};
unsigned long long l,r,mod;
long long mul(long long x,long long y)
{
if (x<y) swap(x,y);
register long long z=;
for (;y;y>>=,x<<=,x=x>=mod?x-mod:x) if (y&) z+=x,z=z>=mod?z-mod:z;
return z;
}
matrix multiply(matrix a,matrix b)
{
unsigned long long sum=;
matrix c;
memset(c.mat,,sizeof(c.mat));
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
sum=;
for(int k=;k<=;k++)
{
long long numqq=mul(a.mat[i][k],b.mat[k][j]);
if(mod>)sum+=numqq,sum%=mod;
else sum+=(a.mat[i][k]*b.mat[k][j])%mod;
}
c.mat[i][j]=sum;
}
return c;
}
matrix matmod(matrix a,unsigned long long k)
{
matrix res;
memset(res.mat,,sizeof(res.mat));
for(int i=;i<=;i++)res.mat[i][i]=;
while(k)
{
if(k&)res=multiply(res,a);
k>>=;
a=multiply(a,a);
}
return res;
}
unsigned long long work(unsigned long long x)
{
if(x==)return ;
if(x==)return ;
if(x==)return ;
matrix a,b;
memset(a.mat,,sizeof(a.mat));
memset(b.mat,,sizeof(b.mat));
for(int i=;i<=;i++)a.mat[i][]=;
for(int i=;i<=;i++)b.mat[i][]=;
a.mat[][]=;
a=matmod(a,x);
a=multiply(a,b);
return (a.mat[][]-+mod)%mod;
}
int main(){
freopen("artist.in","r",stdin);
freopen("artist.out","w",stdout);
scanf("%d%lld",&n,&mod);
for(int i=;i<=n;i++)
{
scanf("%lld%lld",&l,&r);
unsigned long long num1=,num2=;
num1=work(l-);
num2=work(r);
unsigned long long ans=num2-num1+mod;
printf("%lld\n",ans%mod);
}
return ;
fclose(stdin);
fclose(stdout);
}
小红帽的画笔(NOIP模拟赛Round 7)的更多相关文章
- 水(NOIP模拟赛Round #10)
题目描述: 小Z有一个长度为的数列.他有次令人窒息的操作,每次操作可以使某个数字或.他当然是希望这些数字的乘积尽量小了.为了简化题目,你只需输出操作完成后的数列即可. ———————————————— ...
- YYH的营救计划(NOIP模拟赛Round 6)
题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!YYH感动的热泪盈眶,开起了门…… YYH的父亲下班回家,街坊邻居说YYH被一群陌生人强行押上了警车!YYH的父 ...
- 题(NOIP模拟赛Round #10)
题目描述: 有一张的地图,其中的地方是墙,的地方是路.有两种操作: 给出个地点,询问这个地点中活动空间最大的编号.若询问的位置是墙,则活动空间为:否则活动空间为询问地点通过四联通能到达的点的个数.如果 ...
- 大(NOIP模拟赛Round #10)
题目描述: 小Z有个n个点的高清大图,每个点有且只有一条单向边的出边.现在你可以翻转其中的一些边,使他从任何一个点都不能通过一些道路走回这个点.为了方便,你只需输出方案数对取模即可.当在两个方案中有任 ...
- bananahill(NOIP模拟赛Round 8)
题目描述 香蕉川由座香蕉山组成,第i座山有它的高度.小Z准备从左到右爬这里的恰好座香蕉山,但他不希望山的高度起伏太大,太过颠簸,会让本就体育不好的他过于劳累.所以他定义了爬山的劳累度是所有爬的相邻的两 ...
- 战斗机的祈雨仪式(NOIP模拟赛Round 7)
[问题描述] 炎炎夏日,如果没有一场大雨怎么才能尽兴?秋之国的人民准备了一场祈雨仪式.战斗机由于拥有操纵雷电的能力,所以也加入了其中,为此,她进行了一番准备. 战斗机需要给自己的Spear of Lo ...
- 魔法使的烟花(NOIP模拟赛Round 7)
[问题描述] 魔法森林里有很多蘑菇,魔法使常常采摘它们来制作魔法药水.为了在6月的那个奇妙的晚上用魔法绽放出最绚丽的烟花,魔法使决定对魔法森林进行一番彻底的勘探. 魔法森林分为n个区域,由n-1条长度 ...
- 灰姑娘的水晶鞋(NOIP模拟赛Round 7)
[问题描述] 传说中的水晶鞋有两种颜色:左边的水晶鞋是红色,右边的是蓝色,据说穿上它们会有神奇的力量. 灰姑娘要找到她所有的n双水晶鞋,它们散落在一条数轴的正半轴上,坐标各不相同,每双水晶鞋还有一个权 ...
- YYH的球盒游戏(NOIP模拟赛Round 6)
题目描述 YYH有一些总共有种颜色的球,他有颜色的球个.他同样有个盒子,第个盒子能放个球. 他的目标是把这个球按规则放进个盒子里: 对于一个盒子,对于每种颜色的球至多只能放个. 把颜色为的球放进盒子, ...
随机推荐
- SQL Server 数据库内部版本号
数据库还原或版本升级出现版本错误时可参考 可以利用SQL语句查看本机数据库版本:select @@VERSION 如果你不确定是源数据库的版本,下面的映射表的SQL Server版本的内部版本号,以便 ...
- Dawson City【道森市】
Dawson City Cities usually have a good reason for being where they are, like a nearby port or river. ...
- 为什么C++编译器不能支持对模板的分离式编译
首先,一个编译单元(translation unit)是指一个.cpp文件以及它所#include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个 ...
- perl连接mysql数据库
首先需要安装 ppm install DBD::mysql use strict; use DBI; my $host = "localhost"; # 主机地址 my $driv ...
- K-均值聚类——电影类型
K-均值聚类 K-均值算法试图将一系列样本分割成K个不同的类簇(其中K是模型的输入参数),其形式化的目标函数称为类簇内的方差和(within cluster sum of squared errors ...
- url_maneger.py
coding=UTF-8 # url管理器 class urlManeger: def __init__(self): self.new_urls = set() self.old_urls = se ...
- 进入saftmode解决方案
Name node is in safe mode.The reported blocks 356 needs additional 2 blocks to reach the threshold 0 ...
- Python zip()函数实现并行迭代
示例1: for i, j in zip(range(0, 10), range(1, 11)): print(i, j) 输出结果: 0 11 22 33 44 55 66 77 88 99 10 ...
- CSS UNIT 详解以及最佳实践
分类 ■ 绝对长度(Absolute units):cm,mm,in,pt,pc 绝对单位之间的换算:1in = 2.54cm=25.4mm=72pt=6pc 绝对长度在css中的表现和其他地方 ...
- Jforum环境搭建
前提:搭建好JDK.JRE.Tomcat.数据库 1.之前安装了Navicat Premium,所以直接用这个创建名为jforum的MySQL数据库,默认密码为空,记得设置密码,因为Jforum要用到 ...