Sequence( 分块+矩阵快速幂 )

题目链接

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  #define e exp(1)
 4  #define pi acos(-1)
 5  #define mod 1000000007
 6  #define inf 0x3f3f3f3f
 7  #define ll long long
 8  #define ull unsigned long long
 9  #define mem(a,b) memset(a,b,sizeof(a))
10 int gcd(int a,int b){return b?gcd(b,a%b):a;}
11 
12 ll A,B,C,D,N,P;
13 struct mat {
14     ll a[3][3];
15 }c;
16 
17 mat mat_mul(mat x,mat y) {
18     mat s;
19     mem(s.a,0);
20     for(int i=0;i<3;i++)
21         for(int j=0;j<3;j++)
22         for(int k=0;k<3;k++)
23         s.a[i][j]=(s.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
24     return s;
25 }
26 
27 mat mat_pow(ll n) {
28     mat res;
29     mem(res.a,0);
30     res.a[0][0]=res.a[1][1]=res.a[2][2]=1;
31     while(n) {
32         if(n&1) res=mat_mul(res,c);
33         c=mat_mul(c,c);
34         n>>=1;
35     }
36     return res;
37 }
38 
39 ll solove(ll i) {
40     ll l=i,r=N;
41     ll p=P/i;
42     while(l<r) {
43         int mid=r-(r-l)/2;
44         if(p==P/mid) l=mid;
45         else if(p>P/mid)r=mid-1;
46         else l=mid+1;
47     }
48     return l;
49 }
50 
51 int main() {
52     int T;scanf("%d",&T);
53     while(T--) {
54         scanf("%lld%lld%lld%lld%lld%lld",&A,&B,&C,&D,&P,&N);
55         if(N==1){printf("%lld\n",A);continue;}
56         if(N==2){printf("%lld\n",B);continue;}
57         ll f1=B; ll f2=A; mat ans;
58         for(ll i=3; i<=N;) {
59             ll j=solove(i);
60             mem(c.a,0);
61             c.a[0][0]=D;c.a[0][1]=C;
62             c.a[2][2]=1;c.a[1][0]=1;
63             c.a[0][2]=P/i; ans=mat_pow(j-i+1);
64             ll ff1=(ans.a[0][0]*f1%mod+ans.a[0][1]*f2%mod+ans.a[0][2])%mod;
65             ll ff2=(ans.a[1][0]*f1%mod+ans.a[1][1]*f2%mod+ans.a[1][2])%mod;
66             f1=ff1; f2=ff2; i=j+1;
67         }
68         printf("%lld\n",f1);
69     }
70     return 0;
71 }

 

posted @ 2018-11-01 17:56  ouyang_wsgwz  阅读(289)  评论(0编辑  收藏  举报