CodeForces 60 E.Mushroom Gnomes(矩阵快速幂)
2017-12-23 21:30
344 查看
Description
给出n个有序的整数ai,前x秒,每秒相邻两个数之间会多一个数,其值为这两个数的和,之后把所有数字排序,最后y秒依旧是两个数之间多一个这两个数的和,问最后得到的所有数字之和
Input
第一行输入四个整数n,x,y,p,之后输入不减的n个整数ai
(1≤n≤106,0≤x,y≤1018,x+y>0,2≤p≤109,0≤ai≤109)
Output
输出最后的得到的数字之和,结果模p之后输出
Sample Input
2 1 0 657276545
1 2
Sample Output
6
Solution
先不考虑排序,只需分析x秒后得到的数字之和中每个数被用了多少次即可
先考虑相邻的两个数,以a,b为例
第一秒后变成a,a+b,b,和为2a+2b
第二秒后变成a,2a+b,a+b,a+2b,b,和为5a+5b
第三秒后变成a,3a+b,2a+b,3a+2b,a+b,2a+3b,a+2b,a+3b,b,和为14a+14b
可以看出第x秒后和为1+∑i=0x−13i=3x+12
现在考虑整个序列,由于最小值和最大值只和一个数相邻,故其x秒后出现了3x+12次,但是其他值两边都会被用,故出现了2⋅3x+12−1=3x次,用矩阵快速幂可以求出3x+12和3x
再考虑排序,由于后y秒和前x秒过程一样,只要求出x秒后序列的最值与和即可,x秒后序列最小值显然是a1,下面求最大值
显然最大值是通过原先的最大值mx和次大值smx生成的,依旧是上面的例子,可以看出mx在x秒后最大值中出现f(x)次,smx在x秒后最大值中出现f(x−1)次,其中f(1)=1,f(2)=2,f(n)=f(n−1)+f(n−2)为斐波那契数列,依旧可以用矩阵快速幂求出
Code
给出n个有序的整数ai,前x秒,每秒相邻两个数之间会多一个数,其值为这两个数的和,之后把所有数字排序,最后y秒依旧是两个数之间多一个这两个数的和,问最后得到的所有数字之和
Input
第一行输入四个整数n,x,y,p,之后输入不减的n个整数ai
(1≤n≤106,0≤x,y≤1018,x+y>0,2≤p≤109,0≤ai≤109)
Output
输出最后的得到的数字之和,结果模p之后输出
Sample Input
2 1 0 657276545
1 2
Sample Output
6
Solution
先不考虑排序,只需分析x秒后得到的数字之和中每个数被用了多少次即可
先考虑相邻的两个数,以a,b为例
第一秒后变成a,a+b,b,和为2a+2b
第二秒后变成a,2a+b,a+b,a+2b,b,和为5a+5b
第三秒后变成a,3a+b,2a+b,3a+2b,a+b,2a+3b,a+2b,a+3b,b,和为14a+14b
可以看出第x秒后和为1+∑i=0x−13i=3x+12
现在考虑整个序列,由于最小值和最大值只和一个数相邻,故其x秒后出现了3x+12次,但是其他值两边都会被用,故出现了2⋅3x+12−1=3x次,用矩阵快速幂可以求出3x+12和3x
再考虑排序,由于后y秒和前x秒过程一样,只要求出x秒后序列的最值与和即可,x秒后序列最小值显然是a1,下面求最大值
显然最大值是通过原先的最大值mx和次大值smx生成的,依旧是上面的例子,可以看出mx在x秒后最大值中出现f(x)次,smx在x秒后最大值中出现f(x−1)次,其中f(1)=1,f(2)=2,f(n)=f(n−1)+f(n−2)为斐波那契数列,依旧可以用矩阵快速幂求出
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; typedef ll M[2][2]; int n,p; ll x,y; void Mul(M &A,M B) { M C; for(int i=0;i<2;i++) for(int j=0;j<2;j++) { C[i][j]=0; for(int k=0;k<2;k++)C[i][j]+=A[i][k]*B[k][j]; } for(int i=0;i<2;i++) for(int j=0;j<2;j++) A[i][j]=C[i][j]%p; } void Pow(M &A,ll k) { M B; B[0][0]=B[1][1]=1; B[0][1]=B[1][0]=0; while(k) { if(k&1)Mul(B,A); Mul(A,A); k>>=1; } for(int i=0;i<2;i++) for(int j=0;j<2;j++) A[i][j]=B[i][j]; } int main() { while(~scanf("%d%I64d%I64d%d",&n,&x,&y,&p)) { int mn,mx,smx,sum=0; for(int i=1;i<=n;i++) { int temp; scanf("%d",&temp); temp%=p; sum+=temp; if(sum>=p)sum-=p; if(i==1)mn=temp; if(i==n-1)smx=temp; if(i==n)mx=temp; } if(n==1)printf("%d\n",mn); else { if(x==0)swap(x,y); M A; A[0][0]=A[0][1]=1,A[1][0]=0,A[1][1]=3%p; Pow(A,x-1); int a=(A[0][0]+A[0][1]*3%p+1)%p,b=A[1][1]*3%p; sum=((ll)a*(mn+mx)%p+(ll)((sum-mn-mx)%p+p)%p*b%p)%p; A[0][0]=A[0][1]=A[1][0]=1,A[1][1]=0; Pow(A,x); a=A[0][0],b=A[1][0]; mx=((ll)a*mx%p+(ll)b*smx%p)%p; if(y==0)a=1,b=1; else { A[0][0]=A[0][1]=1,A[1][0]=0,A[1][1]=3%p; Pow(A,y-1); a=(A[0][0]+A[0][1]*3%p+1)%p,b=A[1][1]*3%p; } sum=((ll)a*(mn+mx)%p+(ll)((sum-mn-mx)%p+p)%p*b%p)%p; printf("%d\n",sum); } } return 0; }
相关文章推荐
- CodeForces 385E Bear in the Field(矩阵快速幂)
- Jzzhu and Sequences CodeForces - 450B 矩阵快速幂
- Jzzhu and Sequences CodeForces - 450B (矩阵快速幂)
- [矩阵快速幂加速DP]Codeforces 717D Bubble Cup 9 -Finals D. Dexterina’s Lab
- Codeforces 691E Xor-sequences【矩阵快速幂,好题】
- CodeForces - 226A Flying Saucer Segments 矩阵快速幂或等比数列求和
- Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]
- CodeForces 719E Sasha and Array 【线段树】【快速矩阵幂】
- codeforces 450-B Jzzhu and Sequences 矩阵快速幂
- codeforces 678D Iterated Linear Function 矩阵快速幂
- Codeforces 514E Darth Vader and Tree DP + 矩阵快速幂
- CodeForces 185A. Plant(矩阵快速幂) 构造
- Codeforces 450B Jzzhu and Sequences(矩阵快速幂)
- Codeforces 450B Jzzhu and Sequences(矩阵快速幂)
- CodeForces - 185A Plant 矩阵快速幂
- codeforces 691E Xor-sequences 矩阵快速幂
- CodeForces 678D Iterated Linear Function 矩阵快速幂
- Codeforces 450B f【n】=f【n-1】-f【n-2】(矩阵快速幂,裸题)
- codeforces 185A 矩阵快速幂
- CodeForces 450B Jzzhu and Sequences 矩阵快速幂