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
原文地址:https://www.cnblogs.com/117208-/p/5342904.html