补坑。
10.14继续复习yl讲课内容,主要纠结了st表
至于线段树和树状数组以后再补坑
首先是关于st表的基本操作
st表可以用于查询某个区间的最小值和最大值,也就是多次询问的RMQ问题。其最精妙之处在于查询操作复杂度只为O(1),预处理时间复杂度为O(nlogn)。
首先是预处理以及输入部分
void rmp_init()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
f[i][0]=a[i];//将每个长度为1的区间赋初值。
}
//f[j][i]表示从j开始2的i次方区间内的最小值
for(int j=2,i=1;j<=n;i++,j*=2)
for(int k=1;j+k-1<=n;k++)
{
f[k][i]=min(f[k][i-1],f[k+j/2][i-1]);//合并两个区间
}
}
查询操作代码
for (int i=1;i<=shu;i++)
{
scanf("%d%d",&l,&r);//输入查询区间
int p=int (log(r-l+1)/log(2)+0.001);//运用换底公式计算出p为区间的i值
int ans=min(f[l][p],f[r-(1<1][p]);//合并两个长度为2的p次方的区间
printf("%d",ans);
}
练习题洛谷P2251
题目背景
无
题目描述
为了检测生产流水线上总共N件产品的质量,我们首先给每一件产品打一个分数A表示其品质,然后统计前M件产品中质量最差的产品的分值Q[m] = min{A1, A2, … Am},以及第2至第M + 1件的Q[m + 1], Q[m + 2] … 最后统计第N - M + 1至第N件的Q[n]。根据Q再做进一步评估。
请你尽快求出Q序列。
输入输出格式
输入格式:
输入共两行。
第一行共两个数N、M,由空格隔开。含义如前述。
第二行共N个数,表示N件产品的质量。
输出格式:
输出共N - M + 1行。
第1至N - M + 1行每行一个数,第i行的数Q[i + M - 1]。含义如前述。
简单的st表应用,附上题解
#include
#include
#include
using namespace std;
int a[1000001],f[1000000][20],n,m;
void rmq_init()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
f[i][0]=a[i];
}
for(int i=1,j=2;j<=n;i++,j*=2)
for(int k=1;k+j-1<=n;k++)
{
f[k][i]=min(f[k][i-1],f[k+j/2][i-1]);
}
}
int main()
{
rmq_init();
int p,s,l,r,ans;
for(int i=1;i<=n-m+1;i++)
{
p=int(log(m)/log(2)+0.001);
ans=min(f[i][p],f[i+m-(1<printf("%d\n",ans);
}
}
10.15学习总结
比较懒,两篇放在一起了
今天结束了yl的坑,开始复习ht讲的图论算法,首先是Bellman-Ford算法。作为一种求单源最短路径的算法,其可怕的时间复杂度使人望而生畏,但我还是不要命→_→的打了一遍。其思想就是不断的对所有边进行松弛,共循环n遍,然后遍历所有边判断是否能继续对其进行松弛,如还能进行松弛则该图为带有负权环的图。
具体代码实现
bool Bellman_Ford()
{
for(int i=1;i<=nodenum;++i)
dis[i]=(i == original?0:MAX);
for(int i=1;i<=nodenum;++i)
for(int j=1;j<=edgenum;++j)
if(dis[edge[j].v]>dis[edge[j].u]+edge[j].cost)//判断能否松弛
{
dis[edge[j].v]=dis[edge[i].u]+edge[i].cost;//松弛
pre[edge[j].v]=edge[j].u;//记录
}
bool flag=1;
for(int i=1;i<=edgenum;++i)
if(dis[edge[i].v]>dis[edge[i].u]+edge[i].cost)
{
flag=0;//判断能否继续松弛
break;
}
return flag;
}
下午纠结了一下午邻接表。
另外记录一个spfa的模版
int spfa_bfs(int s)
{
queue<int>q;
memset(d,0x3f,sizeof(d));
d[a]=0;
memset(c,0,sizeof(c));
memset(vis,0,sizeof(vis));
q.push(s);vis[s]=1;c[s]=1;
int OK=1;
while(!q.empty())
{
int x;
x=q.front();q.pop();vis[x]=0;
for(int k=f[x];k!=0;k=next[k];)
{
int y=v[k];
if(d[x]+w[k]if(!vis[y])
{
vis[y]=1;
c[y]++;
q.push(y);
if(c[y]>n)
return OK=0;
}
}
}
}
return OK;
}
好几天没写学习总结,补坑- -