寒假 Day 1
标签(空格分隔): 未分类
一、树状数组Bit
1.红色的幻想乡
是一道树状数组的题,主要考察对于树状数组的深度理解。
树状数组主要运用于单点修改和区间查询。
这道题的难在于处理二维的矩阵中的bit。
!!放过的行数×行长度+放过的列数×列长度-抵消块数
横竖两个树状数组进行维护
二、关于RMQ
RMQ是一种集二分递推和动态规划思想于一身的诡异算法。
RMQ主要用于查询区间最大最小值,ps :同样可以考虑用线段树解决
RMQ是最大最小值的最好伙伴!!!
1.忠诚(RMQ板子题)
#include<bits/stdc++.h>
using namespace std;
int a[100001],Fmin[100002][30],n,m;
void STmin(){
int k=log(n)/log(2);
for(int i=1;i<=n;i++)
Fmin[i][0]=a[i];
for(int j=1;j<=k;j++)
for(int i=1;(i+(1<<j)-1)<=n;i++)
Fmin[i][j]=min(Fmin[i][j-1],Fmin[i+(1<<(j-1))][j-1]);
}
int RMQmin(int L,int R){
int k=log(R-L+1)/log(2);
return min(Fmin[L][k],Fmin[R-(1<<k)+1][k]);
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
STmin();
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
cout<<RMQmin(x,y)<<" ";
}
return 0;
}
三、矩阵的运算
矩阵乘法的基础
简单的说矩阵就是二维数组,数存在里面,矩阵乘法的规则:A*B=C
其中c[i][j]为A的第i行与B的第j列对应乘积的和,即:
http://www.cnblogs.com/hadilo/p/5865541.html理解
(1)矩阵快速幂
主要通过把数放到矩阵的不同位置,然后把普通递推式变成”矩阵的等比数列”,最后快速幂求解递推式:
通过把原本的递推式转化成矩阵乘法,再用矩阵快速幂求解。
第一步先要列出递推式
第二步是建立矩阵递推式,找到转移矩阵
建立矩阵递推式的基本方法:
一般An与A(n-1)都是按照原始递推式来构建的,当然可以先猜一个An,主要是利用矩阵乘法凑出矩阵T,第一行一般就是递推式,后面的行就是不需要的项就让与其的相乘系数为0。矩阵T就叫做转移矩阵(一定要是常数矩阵),它能把A(n-1)转移到A(n);然后这就是个等比数列,直接写出通项:此处A1叫初始矩阵。所以用一下矩阵快速幂然后乘上初始矩阵就能得到An,这里An就两个元素(两个位置),根据自己设置的A(n)对应位置就是对应的值。
我明白啦哈哈哈哈哈
1.斐伯纳契数列
2.Matrix Power Series巨火题!
如果说Fibonacci考察的主要是数数之前连接而成的矩阵乘法快速幂
那么MPS考察的就是矩阵与矩阵之间构造递推式。
两个具有特殊性质的矩阵
零矩阵(全都是0)乘任何矩阵是零矩阵;
单位矩阵(对角线都是1)乘任何矩阵都是原矩阵本身
贴上一份矩阵快速幂的板子
#include<cstdio>
#include<iostream>
using namespace std;
const int mod=1e9+7;
#define LL long long
LL n,k;
struct Matrix{
LL s[202][202];
}A,B,blank;
inline Matrix operator * (Matrix a,Matrix b)
{
Matrix now=blank;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
now.s[i][j]=(now.s[i][j]+a.s[i][k]*b.s[k][j]%mod)%mod;
return now;
}
inline void Fast_pow(Matrix a,LL b)
{
for(int i=0;i<n;i++)B.s[i][i]=1;
while(b)
{
if(b&1)B=B*a;
a=a*a;
b>>=1;
}
}
int main()
{
scanf("%lld%lld",&n,&k);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%lld",&A.s[i][j]);
Fast_pow(A,k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)printf("%lld ",B.s[i][j]);
putchar('\n');
}
return 0;
}