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. mvc的model验证,ajaxhelper,验证机制语法

    ajaxhelper: onsuccess是调用成功后显示方法,还有一个方法是调用前显示 model验证: 控件前端验证: 需要引入的JS 其中第二个是ajaxhelper的必须验证 后台的两个同名不 ...

  2. Educational Codeforces Round 11 _D

    http://codeforces.com/contest/660/problem/D 这个题据说是很老的题了 然而我现在才知道做法 用map跑了1953ms: 题目大意 给你n个点的坐标 求这些点能 ...

  3. 结合浅层高层特征的paper总结

    1.ION:在conv3.conv4.conv5和context features上分别进行roi_pooling,在channel那一维进行concat 2.Hypernet:在较浅层max_poo ...

  4. Mybatis generator自动生成代码包括实体,dao,xml文件

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...

  5. 电脑上文件的后缀名被隐藏,把一个文本文件改成.bat时,默认打开的还是文本。

    1.打开文件夹,选择组织,点击“文件夹和搜索选项”,如图: 2.选择“查看”,找到“隐藏已知文件类型的扩展名”,不要勾选这一项,如图: 3.点击“确定”或者“应用”

  6. POJ 2255 Tree Recovery——二叉树的前序遍历、后序遍历、中序遍历规则(递归)

    1.前序遍历的规则:(根左右) (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 对于图中二叉树,前序遍历结果:ABDECF 2.中序遍历的规则:(左根右) (1)中序遍历左子树 (2)访 ...

  7. 开启和连接mysql服务器(win10为例)

    1.windows图标右键,选择“计算机管理”: 2.展开左边的“ 服务和应用程序” 选项,点击“服务",找到 MySQL 服务器,点击左侧的 "启动",即可完成 MyS ...

  8. 破解点触码的识别之第三方平台超级鹰的SDK(python3版本)

    import requestsfrom hashlib import md5 class Chaojiying(object): def __init__(self, username, passwo ...

  9. tkinter学习-菜单与画布

    阅读目录 Menu 菜单控件 Menubutton 菜单按钮控件 OptionMenu 选项菜单 Canvas 画布控件 Menu: 说明:菜单控件,显示菜单栏,下拉菜单和弹出菜单 属性:创建一个顶级 ...

  10. perl学习之正则表达式

    9    Perl 中的正则表达式 正则表达式的三种形式 正则表达式中的常用模式 正则表达式的 8 大原则 正则表达式是 Perl 语言的一大特色,也是 Perl 程序中的一点难点,不过如果大家能够很 ...