哈哈哈,失踪人员回归。最近总是在忙一些乱七八糟的事情,终于有了一段空闲时间可以刷刷题了。学姐给我准备了kuangbin先生的矩阵专题,作为我的矩阵终结专题。(初学者请先看我的矩阵专题前三篇)
第一题 CodeForces 450B
分析:这道题看似是一道矩阵题,但是实际上是一道模拟题。看题目给出的公式 f(i)=f(i-1)+f(i+1),i>=2,那么转换一下得到了f(i)=f(i-1)-f(i-2),i>=3,当然这题可以使用矩阵快速幂来算,但是多此一举。不妨将f(1)=x f(2)=y代进去计算前几项,那么依次得到 x y y-x -x -y x-y x y ......,我们发现这个数列是有循环节的,而且必定为6,那么只需要计算前六个,n取一下模即可得到答案。注意:x y可能是负数,但是答案一定得是非负整数。
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 200000+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll dat[10]; int main(){ //freopen("d:\\acm\\in.in","r",stdin); ll n; scanf("%I64d %I64d",&dat[1],&dat[2]); dat[1]=(dat[1]+mod)%mod; dat[2]=(dat[2]+mod)%mod; scanf("%I64d",&n); dat[0]=(dat[1]-dat[2]+mod)%mod; for(int i=3;i<6;i++) dat[i]=(dat[i-1]-dat[i-2]+mod)%mod; printf("%I64d\n",dat[n%6]); return 0; }
题目大意:给你一个矩阵,矩阵第一行中,第一个数为空,之后的数就是233,2333,23333。。。一直轮下去。然后,矩阵第一列上,第一个数为空(即第一行第一列的那个数为空),之后的所有数会给出。接着,告诉你这个矩阵其他元素都是按照maze[i][j]=maze[i-1][j]+maze[i][j-1]的规律来计算的,让你求出矩阵右下角的数是多少。
分析:一开始没有往矩阵方面想,前段时间数论做多了之后很容易就发现最后的maze[n][m]的数可以通过已知的数乘一个数(满足一个组合数,杨辉三角),然后相加得到。虽然我公式推出来了,但是复杂度太高,而且写起来还麻烦,就被我pass了,有兴趣的朋友可以自己推一推写一写。然后回过去想矩阵做法的话,立刻就想到了(提示n的值很大,但是m的值不大)。将输入的23(第一个23是补充上去的,为了和之后的23333对齐),maze[1][0],maze[2][0],maze[3][0],......作为初始值,根据公式很容易看出转换的矩阵,除了第一个233是前一个23乘10加3,其他的都是maze[i][j]=maze[i-1][j]+maze[i][j-1]。
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 10+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll mul(ll a,ll b){ ll ans=0; while(b){ if(b&1)ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; } return ans; } struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%10000007; return ans; } }; matrix qlow(matrix a,int n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int n,m; while(~scanf("%d %d",&n,&m)){ matrix ans; ans.init(n+2); for(int i=1;i<=n;i++) scanf("%lld",&ans.maze[0][i]); ans.maze[0][0]=23; ans.maze[0][n+1]=1; matrix ant; ant.init(n+2); for(int i=0;i<=n;i++) ant.maze[0][i]=10,ant.maze[n+1][i]=3; ant.maze[n+1][n+1]=1; for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) ant.maze[i][j]=1; ant=qlow(ant,m); ans=ans*ant; printf("%lld\n",ans.maze[0][n]); } return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- int m; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int n; while(~scanf("%d %d",&n,&m)){ matrix ant; ant.init(2); ant.maze[0][0]=4; ant.maze[1][0]=2; ant.maze[1][1]=1; ant=qlow(ant,n/2); ll ans=ant.maze[1][0]; if(n&1)ans=(ans*2+1)%m; cout<<ans<<endl; } return 0; }
我知道读者肯定没有看懂,无妨,请转到这位大神的博客,他写得很好,这里我贴下我的代码
http://www.cnblogs.com/AOQNRMGYXLMV/p/5256508.html
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 150+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); //const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- int n,m,base,score; unsigned int d[40][10]; struct matrix{ int n; unsigned int maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]+=maze[i][k]*rhs.maze[k][j]; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } unsigned int solve(){ scanf("%d %d",&base,&score); if(base==2)return 1; m=(base-1)*(base-1); n=base*m; for(int i=1;i<base;i++) d[0][i]=1; for(int i=1;i<m;i++) for(int j=0;j<base;j++){ d[i][j]=0; for(int k=0;k<base;k++) if(k!=j&&(j-k)*(j-k)<=i){ d[i][j]+=d[i-(j-k)*(j-k)][k]; } } /*for(int i=0;i<m;i++){ for(int j=0;j<base;j++) cout<<d[i][j]<<" "; cout<<endl; }*/ if(score<m){ unsigned int cnt=0; for(int i=0;i<base;i++) cnt+=d[score][i]; return cnt; } matrix ans; ans.init(n); for(int i=0;i<m;i++) for(int j=0;j<base;j++) ans.maze[0][i*base+j]=d[i][j]; matrix ant; ant.init(n); for(int j=0;j<(m-1)*base;j++) ant.maze[j+base][j]=1; for(int j=(m-1)*base;j<n;j++){ int ss=m,bb=j%base; for(int i=0;i<base;i++) if(i!=bb){ int sst=ss-(i-bb)*(i-bb); if(sst>=0){ ant.maze[sst*base+i][j]=1; } } } /*for(int i=0;i<n;i++){ for(int j=0;j<n;j++) cout<<ant.maze[i][j]<<" "; cout<<endl; }*/ ant=qlow(ant,score-m+1); ans=ans*ant; unsigned int cnt=0; for(int i=0;i<base;i++) cnt+=ans.maze[0][n-1-i]; return cnt; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++) printf("Case %d: %u\n",cas,solve()); return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); //const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- struct matrix{ int n; int maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%6; return ans; } }; matrix qlow(matrix a,int n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int A[1010][10]; int B[10][1010]; int C[1010][10]; int D[1010][1010]; int main(){ //freopen("d:\\acm\\in.in","r",stdin); int n,k; while(scanf("%d %d",&n,&k),n||k){ for(int i=0;i<n;i++) for(int j=0;j<k;j++) scanf("%d",&A[i][j]); for(int i=0;i<k;i++) for(int j=0;j<n;j++) scanf("%d",&B[i][j]); matrix ans; ans.init(k); for(int i=0;i<k;i++) for(int j=0;j<k;j++) for(int h=0;h<n;h++) ans.maze[i][j]=(ans.maze[i][j]+B[i][h]*A[h][j])%6; ans=qlow(ans,n*n-1); for(int i=0;i<n;i++) for(int j=0;j<k;j++){ C[i][j]=0; for(int h=0;h<k;h++) C[i][j]=(C[i][j]+A[i][h]*ans.maze[h][j])%6; } for(int i=0;i<n;i++) for(int j=0;j<n;j++){ D[i][j]=0; for(int h=0;h<k;h++) D[i][j]=(D[i][j]+C[i][h]*B[h][j])%6; } ll ant=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) ant+=D[i][j]; cout<<ant<<endl; } return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 50+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%1000; return ans; } }; matrix qlow(matrix a,int n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int t; scanf("%d",&t); while(t--){ int n,r; scanf("%d %d",&n,&r); matrix ans; ans.init(n); for(int i=0;i<n;i++) scanf("%lld",&ans.maze[0][i]); matrix ant; ant.init(n); for(int i=0;i<n;i++){ int k; scanf("%d",&k); while(k--){ int a; scanf("%d",&a); ant.maze[a][i]=1; } } ant=qlow(ant,r); ans=ans*ant; int cnt=0; for(int i=0;i<n;i++){ if(cnt)putchar(' '); cnt=1; printf("%lld",ans.maze[0][i]); } puts(""); } return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll m; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int t; scanf("%d",&t); while(t--){ ll a,b,n; scanf("%lld %lld %lld %lld",&a,&b,&n,&m); if(n==0){ printf("%lld\n",a); continue; } if(m==1)m=10; else if(m==2)m=100; else if(m==3)m=1000; else m=10000; //cout<<m<<endl; matrix ans; ans.init(2); ans.maze[0][1]=ans.maze[1][0]=ans.maze[1][1]=1; ans=qlow(ans,n-1); printf("%lld\n",(a*ans.maze[0][1]+b*ans.maze[1][1])%m); } return 0; }
分析:以前在poj上做过一个几乎一模一样的,可以用二分做,也可以直接矩阵快速幂。(不明白去看一前面的矩阵专题)注意一下,结束条件。
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 90+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%10; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int n; ll k; while(scanf("%d %lld",&n,&k),n){ matrix ans; ans.init(n<<1); for(int i=0;i<n;i++) for(int j=0;j<n;j++){ scanf("%lld",&ans.maze[i][j]); ans.maze[i][j]%=10; ans.maze[i][j+n]=ans.maze[i][j]; } for(int i=0;i<n;i++)ans.maze[i+n][i+n]=1; ans=qlow(ans,k); for(int i=0;i<n;i++){ int cnt=0; for(int j=0;j<n;j++){ if(cnt)putchar(' '); cnt=1; printf("%lld",ans.maze[i][j+n]); } puts(""); } puts(""); } return 0; }
分析:题目给你a+b与ab的值,让你求出a^n+b^n。题目描述很简单,解法也比较好想到。对于a^n+b^n,那么考虑a^(n-1)+b^(n-1),两者之间的联系是a^n+b^n = [a^(n-1)+b^(n-1)] * (a + b) - ab * (a^(n-2) + b^(n-2)) , n>=2。那么可以构造矩阵
注意:-ab要使用加分逆元变成正数!还有p=0,q=0不一定代表输入结束!(特别坑,在这个地方上耍我,出题人一定缺少关爱!)
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]+=maze[i][k]*rhs.maze[k][j]; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); ll p,q,k; while(scanf("%lld %lld",&p,&q)){ if(!(~scanf("%lld",&k))){ return 0; } if(k==0){ puts("2"); continue; } matrix ans; ans.init(2); ans.maze[0][0]=2;ans.maze[0][1]=p; matrix ant; ant.init(2); ant.maze[1][0]=1;ant.maze[0][1]=-q; ant.maze[1][1]=p; ant=qlow(ant,k-1); ans=ans*ant; cout<<ans.maze[0][1]<<endl; } return 0; }
但是呢,有个小问题,这个矩阵太大了,n可以到500,说不定会超时(我没写过,不知道是不是一定超时)。然后这里需要用到同构矩阵优化,用一维数组模拟二维矩阵乘法。(写这道题的时候,脑子特别不清醒,想了好久才把对应关系找到,汗)不知道的可以看我前面的矩阵专题!
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 500+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); //const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll m; struct matrix{ int n; ll maze[maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) ans.maze[i]=(ans.maze[i]+maze[(i+n-j)%n]*rhs.maze[j])%m; return ans; } }; matrix qlow(matrix a,int n){ matrix ans; ans.init(a.n); ans.maze[0]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } ll dat[maxn]; int main(){ //freopen("d:\\acm\\in.in","r",stdin); int n,d,k; while(~scanf("%d %lld %d %d",&n,&m,&d,&k)){ for(int i=0;i<n;i++) scanf("%lld",&dat[i]); matrix ans; ans.init(n); ans.maze[0]=1; for(int i=1;i<=d;i++) ans.maze[i]=ans.maze[n-i]=1; ans=qlow(ans,k); /*for(int i=0;i<n;i++) cout<<ans.maze[i]<<" "; cout<<endl;*/ int cnt=0; for(int i=0;i<n;i++){ if(cnt)putchar(' '); cnt=1; ll ant=0; for(int j=0;j<n;j++) ant=(ant+dat[j]*ans.maze[(j+n-i)%n])%m; printf("%lld",ant); } puts(""); } return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); //const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- const ll mm = 987654321ll; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%mm; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int p; while(scanf("%d",&p),p){ if((p&1)||p<8){ puts("0"); continue; } matrix ans; ans.init(2); ans.maze[0][0]=ans.maze[1][0]=ans.maze[0][1]=1; ans=qlow(ans,p-4); printf("%lld\n",(ans.maze[0][0]-p/2+1+mm)%mm); } return 0; }
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 80+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%mod; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); ll n; int k; scanf("%I64d %d",&n,&k); if(n==1){ puts("1"); return 0; } matrix ans; ans.init(2*(k+1)+1); for(int i=0;i<k+1;i++) ans.maze[0][i]=1; for(int i=k+1;i<2*(k+1);i++) ans.maze[0][i]=(ans.maze[0][i-1]<<1)%mod; ans.maze[0][2*(k+1)]=ans.maze[0][2*(k+1)-1]+1; //for(int i=0;i<=2*(k+1);i++) // cout<<ans.maze[0][i]<<endl; matrix ant; ant.init(2*(k+1)+1); for(int i=0;i<k+1;i++) ant.maze[i+k+1][i]=1; ant.maze[k+1][k+1]=1; for(int j=1;j<k+1;j++) for(int i=0;i<=j;i++) ant.maze[i+k+1][j+k+1]=(ant.maze[k+1+i][k+j]+ant.maze[i+k][j+k])%mod; for(int j=0;j<k+1;j++) for(int i=0;i<=j;i++) ant.maze[i][j+k+1]=ant.maze[i+k+1][j+k+1]*(1ll<<(j-i))%mod; for(int i=0;i<2*(k+1);i++) ant.maze[i][2*(k+1)]=ant.maze[i][2*(k+1)-1]; ant.maze[2*(k+1)][2*(k+1)]=1; //for(int i=0;i<=2*(k+1);i++){ // for(int j=0;j<=2*(k+1);j++) // cout<<ant.maze[i][j]<<" "; // cout<<endl; //} ant=qlow(ant,n-2); ans=ans*ant; printf("%I64d\n",ans.maze[0][2*(k+1)]); return 0; }
分析:这道就是题目难懂,解法上是一道常规的矩阵题。(题目意思太麻烦了,自己百度把)
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll x; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator *(const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%x; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); ll sx,sy,dx,dy,t; scanf("%I64d %I64d %I64d %I64d %I64d %I64d",&x,&sx,&sy,&dx,&dy,&t); matrix ans; ans.init(6); ans.maze[0][0]=ans.maze[0][1]=ans.maze[1][1]=1; ans.maze[1][2]=ans.maze[1][3]=ans.maze[1][4]=1; ans.maze[1][5]=ans.maze[2][4]=ans.maze[2][5]=ans.maze[2][3]=1; ans.maze[3][2]=ans.maze[3][4]=ans.maze[3][5]=1; ans.maze[4][2]=ans.maze[4][4]=ans.maze[5][3]=ans.maze[5][5]=1; ans.maze[0][2]=ans.maze[0][3]=ans.maze[0][4]=2; ans.maze[2][2]=ans.maze[3][3]=ans.maze[0][5]=2; ans=qlow(ans,t); matrix ant; ant.init(6); ant.maze[0][0]=1;ant.maze[0][2]=sx-1;ant.maze[0][3]=sy-1; ant.maze[0][4]=(dx%x+x)%x;ant.maze[0][5]=(dy%x+x)%x; ant=ant*ans; printf("%I64d %I64d\n",ant.maze[0][2]+1,ant.maze[0][3]+1); return 0; }
我的代码Visual C++可以过,但是 GNU C++过不了,实在搞不清楚为什么,迷!
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll m; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator *(const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++){ ll n; int anw; scanf("%lld %lld",&n,&m); matrix ans; ans.init(3); ans.maze[0][0]=ans.maze[0][1]=1; ans.maze[0][2]=2; matrix ant; ant.init(3); ant.maze[0][1]=ant.maze[0][2]=ant.maze[1][0]=1; ant.maze[1][1]=ant.maze[1][2]=ant.maze[2][2]=1; ant=qlow(ant,n-2); ans=ans*ant; anw=ans.maze[0][2]; printf("Case %d: ",cas); if(anw==0||anw%2){ puts("No"); } else { puts("Yes"); int cnt=0; for(int i=0;i<anw;i++){ if(cnt)putchar(' '); cnt=1; putchar('1'); } puts(""); cnt=0; for(int i=0;i<anw;i++){ if(cnt)putchar(' '); cnt=1; if(i==0)putchar('0'); else printf("-1"); } puts(""); for(int i=0;i<anw-2;i++){ cnt=0; if(i<(anw-2)/2){ for(int j=0;j<anw;j++){ if(cnt)putchar(' '); cnt=1; if(j<i+2)putchar('1'); else printf("-1"); } } else { for(int j=0;j<anw;j++){ if(cnt)putchar(' '); cnt=1; if(j<i+1)putchar('1'); else if(j==i+1)putchar('0'); else printf("-1"); } } puts(""); } } } return 0; }
第十五题 UVA 10518
分析:题目首先得看懂,不懂的自己百度把。其实就是求一个类斐波那契数列,F(1)=1,F(2)=1,F(i)=F(i-1)+F(i-2)+1,i>=3
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 10+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll b; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator * (const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%b; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); ll n; int cas=1; while(scanf("%lld %lld",&n,&b),n||b){ matrix ans; ans.init(3); ans.maze[0][0]=ans.maze[0][2]=1; ans.maze[1][2]=ans.maze[2][1]=ans.maze[2][2]=1; printf("Case %d: %lld %lld",cas++,n,b); if(n==0){ printf(" %d\n",1%b); continue; } matrix ant; ant.init(3); ant.maze[0][0]=ant.maze[0][1]=ant.maze[0][2]=1; ans=qlow(ans,n-1); ant=ant*ans; printf(" %lld\n",ant.maze[0][2]); } return 0; }
小结: 总算完成了kuangbin先生的矩阵专题了,已经不记得这是我做完的kuangbin先生的第几个专题了!累!但是满满的充实感!