题面传送门

题意:

给出 \(s_0,s_1,s_2,\dots,s_{n-1}\),对于 \(i\geq n\),有 \(m\) 个 \(s_i\) 满足 \(s_i\neq s_{i\bmod n}\),这 \(m\) 个 \(s_i\) 特殊给定,其它的 \(s_i=s_{i\bmod n}\)。

另有序列 \(f_i\) 满足 \(f_0=0,f_1=1\),\(f_i=f_{i-1}s_{i-1}+f_{i-2}s_{i-2}\)。

求 \(f_x\bmod P\)。

\(1\leq n,m\leq 5\times 10^4,0\leq x\leq 10^{18}\)

Fibo纳粹

粉兔:矩阵快速幂 sb 题。

我:矩阵快速幂神仙题。

这好像是上赛季的一个 jxd 作业。

首先写出矩阵递推式:

\([f_{i-2},f_{i-1}]\times\begin{bmatrix}0&s_{i-2}\\1&s_{i-1}\end{bmatrix}=[f_{i-1},f_i]\)

于是 \([f_{x-1},f_x]=[0,1]\times\prod\limits_{i=1}^{x-1}\begin{bmatrix}0&s_{i-1}\\1&s_{i}\end{bmatrix}\)

首先考虑 \(m=0\) 的情况。后面 \(\prod\) 的矩阵成周期性分部。所以可以求出每个周期内所有矩阵的乘积,跑个矩阵快速幂,最后的零头暴力算一下就可以了。

接下来考虑 \(m\neq 0\) 的情况。记 \(P=\prod\limits_{i=0}^{n-1}\begin{bmatrix}0&s_i\\1&s_{(i+1)\bmod n}\end{bmatrix}\),不难发现,对于大多数周期,其中所有矩阵的乘积都为 \(P\),最多只有 \(2m\) 个周期的乘积 \(\neq P\)。

故可以对这些特殊的周期特殊计算,其它周期跑矩阵快速幂。

考虑一个特殊点 \(x_i\) 会造成什么影响,会使 \(x_i\) 和 \(x_i-1\) 的转移矩阵发生变化。

所以我们对于所有 \(x_i\) 和 \(x_i-1\) 所在的周期单独计算它的贡献。

我们建立 \(n\) 个矩阵 \(A_0,A_1,A_2,\dots,A_{n-1}\),初始 \(A_i=\begin{bmatrix}0&s_i\\1&s_{(i+1)\bmod n}\end{bmatrix}\)

对于某个周期中特殊处理的点 \(p\),我们修改 \(p\bmod n\) 转移矩阵的值,然后求一遍所有 \(A_i\) 的乘积。处理完这个周期后再改回去。

于是此题变为:修改某个矩阵的值,求所有矩阵的乘积。

注意到矩阵是不支持除法操作的,所以这玩意儿只能用线段树维护。

时间复杂度 \(2^3n\log n\)。

细节恶心得要死。。。。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
template<typename T> void read(T &x){
char c=getchar();T neg=1;
while(!isdigit(c)){if(c=='-') neg=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=neg;
}
const int MAXN=5e4;
const int SIZE=2;
ll x;int mod,n,m,k,b[MAXN+5];
pair<ll,int> p[MAXN+5];
ll tk[MAXN*2+5];
struct mat{
int a[SIZE][SIZE];
mat(){memset(a,0,sizeof(a));}
friend mat operator *(mat x,mat y){
mat ret;
for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++)
ret.a[i][j]=(ret.a[i][j]+1ll*x.a[i][k]*y.a[k][j]%mod)%mod;
return ret;
}
};
struct node{int l,r;mat val;} s[MAXN*4+5];
void build(int k,int l,int r){
s[k].l=l;s[k].r=r;if(l==r) return;
int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}
void modify(int k,int p,mat x){
if(s[k].l==s[k].r){s[k].val=x;return;}
int mid=(s[k].l+s[k].r)>>1;
if(p<=mid) modify(k<<1,p,x);else modify(k<<1|1,p,x);
s[k].val=s[k<<1].val*s[k<<1|1].val;
}
mat query(int k,int l,int r){
if(l<=s[k].l&&s[k].r<=r) return s[k].val;
int mid=(s[k].l+s[k].r)>>1;
if(r<=mid) return query(k<<1,l,r);
else if(l>mid) return query(k<<1|1,l,r);
else return query(k<<1,l,mid)*query(k<<1|1,mid+1,r);
}
mat qpow(mat x,ll e){
mat ret;ret.a[0][0]=ret.a[1][1]=1;
while(e){if(e&1) ret=ret*x;x=x*x;e>>=1;}
return ret;
}
map<ll,int> mmp;
signed main(){
// freopen("in.txt","r",stdin);
scanf("%lld%d%d",&x,&mod,&n);x--;
if(x==-1) return printf("0\n"),0;
for(int i=0;i<n;i++) scanf("%d",&b[i]);scanf("%d",&m);
for(int i=1;i<=m;i++) scanf("%lld%d",&p[i].fi,&p[i].se);
for(int i=1;i<=m;i++) mmp[p[i].fi]=p[i].se;
for(int i=1;i<=m;i++){
tk[++k]=p[i].fi;
if(p[i].fi!=n) tk[++k]=p[i].fi-1;
}
sort(tk+1,tk+k+1);k=unique(tk+1,tk+k+1)-tk-1;build(1,0,n-1);
for(int i=0;i<n;i++){
mat t;t.a[0][0]=0;t.a[1][0]=1;t.a[0][1]=b[i];
if(!mmp[i+1]) t.a[1][1]=b[(i+1)%n];else t.a[1][1]=mmp[i+1];
modify(1,i,t);
}
mat ret;
if(x<n) ret=query(1,0,x);
else{
ret=query(1,0,n-1);
if(mmp[n]){
mat t;t.a[0][0]=0;t.a[1][0]=1;t.a[0][1]=b[n-1];t.a[1][1]=b[0];
modify(1,n-1,t);
}
int cur=1,pre=0;ll pn=0;bool flg=0;
while(cur<=k){
// puts("-1");
// printf("%d %d %d\n",cur,pn,pre);
if(x/n<tk[pre+1]/n){
ret=ret*qpow(query(1,0,n-1),(x/n)-pn-1);
ret=ret*query(1,0,x%n);flg=1;break;
}
ret=ret*qpow(query(1,0,n-1),(tk[pre+1]/n)-pn-1);
while(cur<=k&&tk[cur]/n==tk[pre+1]/n){
ll id=tk[cur];int v1,v2;
if(!mmp[id]) v1=b[id%n];else v1=mmp[id];
if(!mmp[id+1]) v2=b[(id+1)%n];else v2=mmp[id+1];
// printf("%lld %d %d %d\n",id,id%n,v1,v2);
mat t;t.a[0][0]=0;t.a[1][0]=1;t.a[0][1]=v1;t.a[1][1]=v2;
modify(1,id%n,t);cur++;
}
if((x/n)==(tk[pre+1]/n)){
ret=ret*query(1,0,x%n);flg=1;break;
} else ret=ret*query(1,0,n-1);
for(int i=pre+1;i<cur;i++){
mat t;t.a[0][0]=0;t.a[1][0]=1;
t.a[0][1]=b[tk[i]%n];t.a[1][1]=b[(tk[i]+1)%n];
modify(1,tk[i]%n,t);
}
pn=tk[pre+1]/n;pre=cur-1;
}
if(!flg){
// puts("-1");
ret=ret*qpow(query(1,0,n-1),(x/n)-pn-1);
ret=ret*query(1,0,x%n);
}
}
mat f;f.a[0][1]=1;f=f*ret;
printf("%d\n",f.a[0][0]);
return 0;
}
/*
3 998244353
3
1 2 1
3
3 3
4 6
10 8 20 998244353
3
100 370 250
5
7 230
23 500
5 480
15 530
19 570 100 998244353
3
1 2 1
2
3 2
5 1 1000000 998244353
3
100 370 250
5
7 230
23 500
5 480
15 530
19 570
*/

Codeforces 575A - Fibonotci的更多相关文章

  1. 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 ...

  2. cf575A Fibonotci

    Fibonotci sequence is an integer recursive sequence defined by the recurrence relation Fn = sn - 1·F ...

  3. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  4. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  5. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  6. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  7. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  8. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  9. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

随机推荐

  1. Python学习系列之一: python相关环境的搭建

    前言 学习python和使用已经一年多了,这段时间抽空整理了一下以前的笔记,方便日后查阅. Python介绍 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Pytho ...

  2. 公众号H5页面接入微信登录流程

    公众号H5页面接入微信登录流程 源码地址 https://gitee.com/szxio/h5_weixin 起步 首先创建一个项目,我们采用uni-app来作为我们的前端框架 环境安装 全局安装vu ...

  3. Nginx(二):Nginx的四层(L4)和七层(L7)负载均衡

    OSI七层模型 和 TCP/IP四层模型 四层负载均衡( L4 Load Balancing ) 四层负载均衡,主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内 ...

  4. PCIe知识摘要记录

    摘: 一. 在PCIe的Spec中,并没有特别详细的关于Root Complex的定义,从实际的角度来讲,可以把Root Complex理解为CPU与PCIe总线系统通信的媒介.Endpoint处于P ...

  5. JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象

    public class Main { public static void main(String[] args) { Chicken c1 = new Chicken(); Chicken c2 ...

  6. hdu 5056 Boring count (类似单调队列的做法。。)

    给一个由小写字母构成的字符串S,问有多少个子串满足:在这个子串中每个字母的个数都不超过K. 数据范围: 1<=T<= 1001 <= the length of S <= 10 ...

  7. SpringCloud微服务实战——搭建企业级开发框架(十二):OpenFeign+Ribbon实现负载均衡

      Ribbon是Netflix下的负载均衡项目,它主要实现中间层应用程序的负载均衡.为Ribbon配置服务提供者地址列表后,Ribbon就会基于某种负载均衡算法,自动帮助服务调用者去请求.Ribbo ...

  8. 详细剖析Spring Cloud 和Spring Cloud Alibaba的前世今生

    我们知道spring cloud可以用来开发微服务,但是应该很少有人真正知道Spring Cloud是什么. 官方的解释是:spring cloud提供了一些可以让开发者快速构建分布式应用的工具,这些 ...

  9. 【浏览器】聊聊DOM

    [浏览器]聊聊DOM 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 作为前端开发,在以前的工作中大多是和DOM打交道,到 ...

  10. "简单"的优化--希尔排序也没你想象中那么难

    写在前边 大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 不过这篇文章呢,还是想跟大家聊一聊数据结构与算法,学校也是大二上才开设了数据结构这 ...