Fibonotci sequence is an integer recursive sequence defined by the recurrence relation

Fn = sn - 1·Fn - 1 + sn - 2·Fn - 2withF0 = 0, F1 = 1

Sequence s is an infinite and almost cyclic sequence with a cycle of length N. A sequence s is called almost cyclic with a cycle of length N if , for i ≥ N, except for a finite number of values si, for which (i ≥ N).

Following is an example of an almost cyclic sequence with a cycle of length 4:

s = (5,3,8,11,5,3,7,11,5,3,8,11,…)

Notice that the only value of s for which the equality does not hold is s6 (s6 = 7 and s2 = 8). You are given s0, s1, ...sN - 1 and all the values of sequence s for which (i ≥ N).

Find .

Input

The first line contains two numbers K and P. The second line contains a single number N. The third line contains N numbers separated by spaces, that represent the first N numbers of the sequence s. The fourth line contains a single number M, the number of values of sequence s for which . Each of the following M lines contains two numbers j and v, indicating that and sj = v. All j-s are distinct.

  • 1 ≤ N, M ≤ 50000
  • 0 ≤ K ≤ 1018
  • 1 ≤ P ≤ 109
  • 1 ≤ si ≤ 109, for all i = 0, 1, ...N - 1
  • N ≤ j ≤ 1018
  • 1 ≤ v ≤ 109
  • All values are integers
Output

Output should contain a single integer equal to .

Examples
Input
10 8
3
1 2 1
2
7 3
5 4
Output
4

感觉是递推神题……f[n]=s[n-1]*f[n-1]+s[n-2]*f[n-2],而且{s[i]}是个T=5w的循环数列,而且还换掉了s[i]当中5w个点……

先不考虑几个s[i]的特殊点

都算到f[1e18]了肯定是要用到矩阵快速幂了

构建矩阵比较简单:

f[n]   f[n-1]        *         s[n]     1           =             f[n+1]      f[n]

0        0                     s[n-1]    0                             0          0

那么

f[1]   f[0]        *            s[1]     1        *      s[2]      1       *  .....  *    s[n-1]     1         =         f[n]      f[n-1]

0        0                      s[0]    0                s[1]      0                        s[n-2]    0                      0          0

然后注意到s[i]是个循环的

所以就是算出一个循环内的转移矩阵的乘积,一个循环是

s[1]     1          ~          s[T]       1

s[0]     0                      s[T-1]    0

接下来直接快速幂即可。

然后考虑挖点的情况:对于一个s[k]的修改,实际上有两个矩阵受到了它的影响:

s[k]      1      和            s[k+1]   1

s[k-1]   0                     s[k]       0

所以每个修改拆成2个对矩阵里头的值的修改。这样就是对矩阵的单点修改不超过10w个

所有s[k]的修改按照k排个序

然后维护一个线段树,保存一个周期内的矩阵的乘积(对你没看错,线段树存的是矩阵)

每次同一个周期内的修改就直接在线段树上单点修改,做完之后ans乘个当前1到T的区间积,然后再单点改回去,下个周期再改。这样每个修改就是logT的

改回去的时候搞个栈就好了

最后输出个答案矩阵的左上角

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 0x7ffffff
#define pa pair<int,int>
#define mkp(a,b) make_pair(a,b)
#define pi 3.1415926535897932384626433832795028841971
using namespace std;
inline LL read()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
LL k,mod,T,C,cnt;
LL s[];
struct matrix{
LL a[][];
inline void init(){a[][]=a[][]=a[][]=a[][]=;}
matrix operator *(matrix b)
{
matrix ans;ans.init();
for (int k=;k<=;k++)
for (int i=;i<=;i++)
for (int j=;j<=;j++)
ans.a[i][j]=(ans.a[i][j]+a[i][k]*b.a[k][j])%mod;
return ans;
}
}ans;
inline matrix getm(LL x)
{
matrix c;
c.a[][]=s[x];c.a[][]=;c.a[][]=s[x-];c.a[][]=;
return c;
}
struct segtree{
int l,r;
matrix m;
}t[];
int zhan[],top;
inline void update(int k){t[k].m=t[k<<].m*t[k<<|].m;}
inline void buildtree(int now,int l,int r)
{
t[now].l=l;t[now].r=r;
if (l==r)
{
t[now].m=getm(l);
return;
}
int mid=(l+r)>>;
buildtree(now<<,l,mid);
buildtree(now<<|,mid+,r);
update(now);
}
inline void change(int now,int x,matrix m)
{
int l=t[now].l,r=t[now].r;
if (l==r){t[now].m=m;return;}
int mid=(l+r)>>;
if (x<=mid)change(now<<,x,m);
else change(now<<|,x,m);
update(now);
}
inline matrix ask(int now,int x,int y)
{
int l=t[now].l,r=t[now].r;
if (l==x&&r==y)return t[now].m;
int mid=(l+r)>>;
if (y<=mid)return ask(now<<,x,y);
else if (x>mid)return ask(now<<|,x,y);
else return ask(now<<,x,mid)*ask(now<<|,mid+,y);
}
inline matrix quickpow(matrix a,LL b)
{
matrix s;s.init();s.a[][]=s.a[][]=;
while (b)
{
if (b&)s=s*a;
a=a*a;
b>>=;
}
return s;
}
struct cg{LL pos,rnk,x,op;}c[],lst;
bool operator <(cg a,cg b){return a.rnk<b.rnk||a.rnk==b.rnk&&a.pos<b.pos;}
bool operator <=(cg a,cg b){return !(b<a);}
int main()
{
k=read();mod=read();T=read();
if (k==){puts("");return ;}
if (k==){printf("%d\n",%mod);return ;}
k--;lst.rnk=k/T+(k%T!=);lst.pos=k%T;if (!lst.pos)lst.pos=T;
for (int i=;i<T;i++)s[i]=read();s[T]=s[];
C=read();
for (int i=;i<=C;i++)
{
LL a=read(),b=read();
c[++cnt].rnk=a/T+(a%T!=);
c[cnt].pos=a%T;if (!c[cnt].pos)c[cnt].pos=T;
c[cnt].x=b;c[cnt].op=; c[++cnt].rnk=a/T+;
c[cnt].pos=a%T+;
c[cnt].x=b;c[cnt].op=;
}
sort(c+,c+cnt+);
buildtree(,,T);
ans.a[][]=;
LL now2=;
for (int i=;i<=cnt;i++)
{
if(c[i]<=lst)
{
if (c[i].rnk-!=now2)
{
ans=ans*ask(,,T);
while (top){change(,zhan[top],getm(zhan[top]));top--;}
now2++;
if(now2!=c[i].rnk-)ans=ans*quickpow(ask(,,T),c[i].rnk--now2),now2=c[i].rnk-;
}
matrix chg=ask(,c[i].pos,c[i].pos);
if (c[i].op==)chg.a[][]=c[i].x;else chg.a[][]=c[i].x;
change(,c[i].pos,chg);
zhan[++top]=c[i].pos;
}else
{
if (now2<lst.rnk-)
{
ans=ans*ask(,,T);
while (top){change(,zhan[top],getm(zhan[top]));top--;}
now2++;
if (now2<lst.rnk-)ans=ans*quickpow(ask(,,T),lst.rnk--now2);
}
ans=ans*ask(,,lst.pos);
printf("%lld\n",ans.a[][]);return ;
}
}
if (now2<lst.rnk-)
{
ans=ans*ask(,,T);
while (top){change(,zhan[top],getm(zhan[top]));top--;}
now2++;
if (now2<lst.rnk-)ans=ans*quickpow(ask(,,T),lst.rnk--now2);
}
ans=ans*ask(,,lst.pos);
printf("%lld\n",ans.a[][]);return ;
}

cf 575A

cf575A Fibonotci的更多相关文章

  1. CF575A Fibonotci [线段树+矩阵快速幂]

    题意 \(s\{\}\) 是一个循环数列 循环节为 \(n\),你可以改掉 \(m\) 项,这 \(m\) 项独立,且不影响循环节 考虑线段树维护矩阵,单点修改最多m次,每次矩阵快速幂就完事了 // ...

  2. Bubble Cup 8 finals A. Fibonotci (575A)

    题意: 定义类循环序列为 长度无限,且除了有限个元素外,均满足s[i] ≡ s[i mod N] (i≥N). 现在有数列F,定义为 F[i] = s[i-2]*F[i-1] + s[i-1]*F[i ...

  3. codeforces575A Fibonotci

    题目大意:f[k]=f[k-1]*s[(n-1)%n]+f[(k-2)]*s[(k-2)%n];会修改某一位置的s值,但循环不变,求f[k]; 矩阵快速幂裸题,由于有修改,所以需要线段树优化 #inc ...

  4. Codeforces 575A - Fibonotci

    题面传送门 题意: 给出 \(s_0,s_1,s_2,\dots,s_{n-1}\),对于 \(i\geq n\),有 \(m\) 个 \(s_i\) 满足 \(s_i\neq s_{i\bmod n ...

  5. 「考试」联赛模拟36-39,noip晚间小测2-3

    36.1 party(CF623D) 很是鸡贼的一道题 首先要明确一点,抓人是有策略,而不是随机的,可以认为等同于按一个给定的顺序猜人,那么这时猜中的概率就只是抓住这个人的概率了 对于每一次猜测,因为 ...

  6. IOI 2020 集训队作业胡扯

    首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...

  7. IOI2020只因训队作业胡做

    w a r n i n g ! 意 识 流 警 告 !!1 不想一个个发了,干脆直接发个合集得了qwq 感觉这辈子都做不完了\(Q\omega Q\) CF516D 写过题解了 CF505E 写过题解 ...

  8. IOI 2020 国家集训队作业

    \(\checkmark\) 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf674G arc103_f \(\checkmark\) cf594E agc034_f agc0 ...

随机推荐

  1. threadLocal遇上线程池导致局部变量变化

    这两天一直在查无线app一个诡异的问题,表象是stg的接口返回数据,和线上接口的返回数据不一致. 1.初步判断:有缓存,查看代码后发现缓存时间直邮6分钟,而且同一个接口,其他调用方的返回数据,stg和 ...

  2. win7 x64和win10 x64 windbg 本地调试记录

    今天看CSDN和某文档看了win7 64位 和win10 64位 的windbg本地调试内核的办法 win7 x64 Step1:kdbgctrl –db Step2:kdbgctrl –e Step ...

  3. Tunneling cannot be enabled without the local_ip bound to an interface on the host. Please configure local_ip 192.168.30.71 on the host interface to be used for tunneling and restart the agen

    按照官方文档配置linux bridge 会出现一下问题 Tunneling cannot be enabled without the local_ip bound to an interface ...

  4. Spring MVC能响应HTTP请求的原因?

    很多Java面试官喜欢问这个问题: 一个Spring MVC的项目文件里,开发人员没有开发自己的Servlet,只通过注解@RequestMapping定义了方法home能响应发向 /mvc/test ...

  5. k8s 创建资源的两种方式【转】

    命令 vs 配置文件 Kubernetes 支持两种方式创建资源: 1. 用 kubectl 命令直接创建,比如: kubectl run nginx-deployment --image=nginx ...

  6. common-fileupload上传图片并显示图片

    效果图如下:                                   代码: 注意:需要jar包:commons-fileupload-1.2.1.jar  和 commons-io-1. ...

  7. Hibernate中get()与load()的区别,以及关于ThreadLocal的使用方法

    一.get方法和load方法的简易理解 (1)get()方法直接返回实体类,如果查不到数据则返回null.load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时 ...

  8. js正则函数match、exec、test、search、replace、split使用集合

    match 方法 使用正则表达式模式对字符串执行查找,并将包含查找的结果作为数组返回. stringObj.match(rgExp) 参数 stringObj 必选项.对其进行查找的 String 对 ...

  9. Bootstrap 响应式表格

    响应式表格 通过把任意的 .table 包在 .table-responsive class 内,您可以让表格水平滚动以适应小型设备(小于 768px).当在大于 768px 宽的大型设备上查看时,您 ...

  10. Fortran学习笔记2(变量声明)

    常数的申明方式 变量初始化 等价申明EQUIALENCE 类型转化 自定义类型 KIND用法 常数的申明方式 程序中所有处理的数据,有些事固定不变的常数,如圆周率π和重力加速度G等. 此时,程序员可以 ...