10.14、10.15学习总结

来源:互联网 发布:爱淘宝每日红包 编辑:程序博客网 时间:2024/06/14 09:36

补坑。
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<<p)+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<cstdio>#include<iostream>#include<cmath>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<<p)][p]);        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]<d[y])            {                d[y]=d[x]+w[k];                if(!vis[y])                {                    vis[y]=1;                    c[y]++;                    q.push(y);                    if(c[y]>n)                        return OK=0;                 }             }         }     }     return OK; }

好几天没写学习总结,补坑- -

0 0