Bubble Cup 8 - Finals [Online Mirror] - A.Fibonotci【分段+ST表】
2015-09-07 08:19
501 查看
因为 sis_i为近似周期序列,而且告诉你了mm个位置以及数字。
那么就将序列分成mm段,每一段用一个ST表来维护区间矩阵乘积
然后注意一些细节,比如mm段分段如果两个不周期位置连续,以及最后一个段等等。
想法还是比价明显的,但是确实不好写….
那么就将序列分成mm段,每一段用一个ST表来维护区间矩阵乘积
然后注意一些细节,比如mm段分段如果两个不周期位置连续,以及最后一个段等等。
想法还是比价明显的,但是确实不好写….
[code]#include<bits/stdc++.h> using namespace std; const int MAXN=50005; int MOD; struct Matrix { int Data[2][2]; }; Matrix operator*(Matrix a,Matrix b) { Matrix c; memset(c.Data,0,sizeof(c.Data)); for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { for(int k=0;k<2;k++) { c.Data[i][j]+=(long long)a.Data[i][k]*b.Data[k][j]%MOD; c.Data[i][j]%=MOD; } } } return c; } int a[MAXN]; pair<long long,int>P[MAXN]; Matrix ST[MAXN][63]; int n; Matrix query(long long l,long long len) { int pos=l%n; Matrix ans; for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { ans.Data[i][j]=i==j?1:0; } } for(int i=0;i<63;i++) { if(len&(1LL<<i)) { ans=ans*ST[pos][i]; pos=(pos+(1LL<<i)%n)%n; } } return ans; } int main() { //freopen("a.txt","r",stdin); long long k; while(~scanf("%I64d%d%d",&k,&MOD,&n)) { for(int i=0;i<n;i++) { scanf("%d",&a[i]); } int m; scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%I64d%d",&P[i].first,&P[i].second); } sort(P,P+m); for(int i=0;i<n;i++) { ST[i][0].Data[0][0]=a[(i-1+n)%n]; ST[i][0].Data[1][0]=a[(i-2+n)%n]; ST[i][0].Data[0][1]=1; ST[i][0].Data[1][1]=0; } for(int j=1;j<63;j++) { for(int i=0;i<n;i++) { ST[i][j]=ST[i][j-1]*ST[(i+(1LL<<(j-1))%n)%n][j-1]; } } Matrix S; S.Data[0][0]=1; S.Data[0][1]=0; if(k==0) { printf("0\n"); continue; } if(k==1) { printf("%d\n",1%MOD); continue; } long long l=1; for(int i=0;i<m;i++) { long long r=P[i].first; if(r>=k) break; S=S*query(l+1,r-l); l=r; //printf("%d-%d %d\n",l,S.Data[0][0],S.Data[0][1]); if(l>=k) break; Matrix tmp; tmp.Data[0][0]=P[i].second; tmp.Data[1][0]=(i==0||P[i-1].first+1!=P[i].first)?a[(r-1+n)%n]:P[i-1].second; tmp.Data[0][1]=1; tmp.Data[1][1]=0; S=S*tmp; l=r+1; //printf("%d--%d %d %d %d\n",l,S.Data[0][0],S.Data[0][1],tmp.Data[0][0],tmp.Data[1][0]); if(l>=k) break; if(i==m-1||P[i].first+1!=P[i+1].first) { tmp.Data[0][0]=a[(r+1)%n]; tmp.Data[1][0]=P[i].second; tmp.Data[0][1]=1; tmp.Data[1][1]=0; S=S*tmp; l=r+2; //printf("%d---%d %d\n",l,S.Data[0][0],S.Data[0][1]); if(l>=k) break; } } S=S*query(l+1,k-l); printf("%d\n",S.Data[0][0]); } return 0; }
相关文章推荐
- 黄聪:TinyMCE 4 增强 添加样式、按钮、字体、下拉菜单和弹出式窗口
- Qt5.2 for Android 配置及部署到手机运行
- 学习日志---哈夫曼树相关算法
- Objective-C 【protocol-协议 的了解使用】
- Objective-C 【protocol-协议 的了解使用】
- SharePoint 2010商业智能组件
- Javascript中Promise对象的实现
- 编译cloog for gcc 4.8.5 问题
- 基于XML的Spring AOP配置
- 数据结构之自建算法库——顺序表
- universalimageloader uil doesn't support scheme(protocol
- HTML学习-网页主体标记body(一)
- 【iOS】iOS开发视图跳转:利用storyboard简单实现视图的跳转与返回
- 线程间的通信——wait()/notify()
- iOS --- 使用RestKit与RESTful web服务器进行简单交互
- TDD LTE 中的HARQ过程
- 5.3.3 可插入的适配器(Pluggable Adapter)
- android自定义View的实现
- ArrayList总结
- 员工管理系统