10.14、10.15学习总结

补坑。
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;
 }

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

你可能感兴趣的:(学习总结)