zoukankan      html  css  js  c++  java
  • codeforces575A Fibonotci

    题目大意:f[k]=f[k-1]*s[(n-1)%n]+f[(k-2)]*s[(k-2)%n];会修改某一位置的s值,但循环不变,求f[k];

    矩阵快速幂裸题,由于有修改,所以需要线段树优化

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define maxn 50005
     5 #define f(c,d) ((1<<(c))*(d))
     6 struct node{
     7     ll x[2][2];
     8 }mt,mi,t,tt,x[17][maxn];
     9 int n,m,p;
    10 ll k,s[maxn],ti;
    11 pair<ll,ll>v[maxn];
    12 node operator * (node a,node b){
    13     node c=mt;
    14     for(int i=0;i<2;++i)
    15         for(int j=0;j<2;++j)    
    16             for(int k=0;k<2;++k)
    17                 c.x[i][j]=(c.x[i][j]+a.x[i][k]*b.x[k][j]%p)%p;
    18     return c;
    19 }
    20 node operator ^ (node a,ll y){
    21     if(y==0)return mi;
    22     node c=a;y--;
    23     while(y){
    24         if(y&1)c=c*a;
    25         y>>=1;a=a*a;
    26     }return c;
    27 }
    28 node ask(int a,int b,int c,int d){
    29     if(f(c,d)==a&&f(c,d+1)==b)return x[c][d];
    30     c--;d=d<<1|1;
    31     if(b<=f(c,d))return ask(a,b,c,d-1);
    32     if(a>=f(c,d))return ask(a,b,c,d);
    33     return ask(a,f(c,d),c,d-1)*ask(f(c,d),b,c,d);
    34 }
    35 node ask(int a,int b){
    36     if(a==b)return mi;
    37     return ask(a,b,16,0);
    38 }
    39 void to(ll a){
    40     if(a/n-ti/n){
    41         t=t*ask(ti%n,n);
    42         t=t*(x[16][0]^(a/n-ti/n-1));
    43         t=t*ask(0,a%n);
    44     }else t=t*ask(ti%n,a%n);
    45     ti=a;
    46 }
    47 int main(){
    48     scanf("%I64d%d",&k,&p);
    49     mi.x[0][0]=mi.x[1][1]=1%p;
    50     scanf("%d",&n);
    51     for(int i=0;i<n;++i)scanf("%I64d",&s[i]);
    52     for(int i=0;i<n;++i){
    53         x[0][i].x[0][1]=s[i]%p;
    54         x[0][i].x[1][0]=1;
    55         x[0][i].x[1][1]=s[(i+1)%n]%p;
    56     }
    57     for(int i=1;i<17;++i)
    58         for(int j=0;f(i,j)<n;++j){
    59             x[i][j]=x[i-1][j<<1];
    60             if(f(i-1,(j<<1|1))<n)x[i][j]=x[i-1][j<<1]*x[i-1][j<<1|1];
    61         }
    62     scanf("%d",&m);
    63     for(int i=0;i<m;++i)scanf("%I64d%I64d",&v[i].first,&v[i].second);
    64     sort(v,v+m);
    65     ti=0;
    66     t=mi;
    67     for(int i=0;i<m;++i){
    68         if(v[i].first>k)break;
    69         if(ti!=v[i].first){
    70             to(v[i].first-1);
    71             tt.x[0][1]=s[ti%n]%p;
    72             tt.x[1][0]=1;
    73             tt.x[1][1]=v[i].second%p;
    74             t=t*tt;
    75             ti++;
    76         }
    77         if(ti==k)break;
    78         ti++;
    79         tt.x[0][1]=v[i].second%p;
    80         tt.x[1][0]=1;
    81         tt.x[1][1]=(v[i+1].first==ti?v[i+1].second:s[ti%n])%p;
    82         t=t*tt;
    83     }
    84     to(k);
    85     printf("%I64d
    ",t.x[1][0]);
    86     return 0;
    87 }
    575A
  • 相关阅读:
    c语言面试基础题
    fwrite(&stud[i],sizeof(struct student_type),1,fp)的基本含义
    对于文件操作函数的记录
    将字符串s1复制到字符串s2。
    将键盘输入的几个数据存储到文件里的程序
    利用指针对二维数组进行遍历查找程序
    常见的C语言错误及程序的调试
    文件的基本操作函数及说明
    一个磁盘信息向另一个磁盘信息的复制
    常用流程图符号和基本流程图
  • 原文地址:https://www.cnblogs.com/117208-/p/5342904.html
Copyright © 2011-2022 走看看