• 20190817考试反思


      考试多思考,认真对待每场考试。

      仍旧一个问题,考到一半就放弃了。主要是怕打不完,T2只码了个暴力,T1没有深度思考,只是在皮上画画写写,也许这种情况下已经没法思考了。下次考试看看能不能静下心来思考,不要慌。

      T1:很好的一道题,想到了要判是不是一些块把某一条路封死了,但是我一想它可能不是一条竖线上就觉得比较麻烦,横着错开比较难判,但是图论就是干这个的,你把所有点向上下边界建边,上边界到下边界的最大值最小的一条路径就是瓶颈,走的时候总会穿过一条最长的路径。这就不用看点与点是不是在一条竖线上,其实是我们不关心它的位置,我只关心点与点的距离,然后这样不关心在坐标轴位置的东西,图论建成边,就能只考虑相对位置了。

     

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int N=6020;
    double d[N];
    bool v[N];
    int pr[N],n,m,k;
    struct point{double x,y;}p[N];
    inline int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar())if(cc=='-') w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    inline double cal(int i,int j)
    {
        if(i==k&&j==k-1) return 0x7fffffff;
        if(j==k&&i==k-1) return 0x7fffffff;
        if(i==k) return m-p[j].y;
        if(j==k) return m-p[i].y;
        if(i==k-1) return p[j].y;
        if(j==k-1) return p[j].y;
        point a=p[i],b=p[j];
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    inline void prim()
    {
        for(int i=1;i<=k;i++) d[i]=0x7fffffff;
        memset(v,0,sizeof(v));
        d[k-1]=0;
        for(int i=1;i<=k;i++)
        {
            int x=0;
            for(int j=1;j<=k;j++)
                if(!v[j]&&(x==0||d[j]<d[x])) x=j;
            v[x]=1;
            for(int j=1;j<=k;j++)
            if(!v[j])
            {
                if(cal(x,j)<d[j])
                {
                    d[j]=cal(x,j);
                    pr[j]=x;
                }
            }
        }
    }
    int main()
    {
        n=rd();m=rd();k=rd();
        for(int i=1;i<=k;i++)
        {
            double x=rd(),y=rd();
            p[i]=(point){x,y};
        }
        k+=2;
        prim();
        int tmp=k;
        double ans=-0x7fffffff;
        while(tmp!=k-1)
        {
            ans=max(ans,d[tmp]);
            tmp=pr[tmp];
        }
        printf("%.10lf
    ",ans/2);
    }
    /*
    g++ -std=c++11 1.cpp -o 1
    ./1
    10 5 2
    1 1 
    2 3
    */
    683ms

      T2:听说是个套路,我用最坏$O(n^{2}logn)$的线段树卡过了。线段树维护单调栈先扔一发

      

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=200020,inf=1e9;
    int p[N],f[N],c[N];
    struct tree{int l,r,w,i,m;}tr[N*4];
    inline int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar()) if(cc=='-')w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    void build(const int k,const int l,const int r)
    {
        if(l==r)
        {
            tr[k].w=inf;
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    }
    int query(const int k,const int x,const int y,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==x&&r==y) return tr[k].i;
        if(y<=mid) return query(k<<1,x,y,l,mid);
        else if(x>mid) return query(k<<1|1,x,y,mid+1,r);
        return max(query(k<<1,x,mid,l,mid),query(k<<1|1,mid+1,y,mid+1,r));
    }
    int ask(const int k,const int x,const int y,const int i,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==r)
        {
            if(tr[k].i<i) return inf;
            return tr[k].w;
        }
        if(y<=mid) return ask(k<<1,x,y,i,l,mid);
        else if(x>mid) return ask(k<<1|1,x,y,i,mid+1,r);
        if(i>tr[k<<1|1].i) return ask(k<<1,x,mid,i,l,mid);
        const int rmax=query(k,mid+1,y,l,r);
        return min(ask(k<<1,x,mid,rmax,l,mid),ask(k<<1|1,mid+1,y,i,mid+1,r));
    }
    void updata(const int k){tr[k].i=max(tr[k<<1].i,tr[k<<1|1].i);}
    void add(const int k,const int id,const int i,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==r)
        {
            tr[k].i=i;
            tr[k].w=f[i];
            return;
        }
        if(id<=mid) add(k<<1,id,i,l,mid);
        else add(k<<1|1,id,i,mid+1,r);
        updata(k);
    }
    int main()
    {
        const int n=rd();
        for(register int i=1;i<=n;i++) p[i]=rd();
        for(register int i=1;i<=n;i++) c[i]=rd();
        build(1,1,n+1);
        memset(f,0x3f,sizeof(f));
        f[0]=0;add(1,1,0,1,n+1);
        for(register int i=1;i<=n;i++)
        {
            const int maxi=0;
            f[i]=ask(1,1,p[i]+1,0,1,n+1)+c[i];
            add(1,p[i]+1,i,1,n+1);
        }
        register int ans=0x7fffffff,maxi=0;
        for(register int i=n;i>=1;i--)
        {
            if(p[i]>maxi)
            {
                ans=min(ans,f[i]);
                maxi=p[i];
            }
        }
        printf("%d
    ",ans);
    }
    /*
    g++ -std=c++11 1.cpp -o 1
    ./1
    5
    3 1 4 5 2
    3 4 3 4 1
    */
    3941ms

      T3:好题,斜率优化,维护下凸包,skyh好像用的栈,加上启发式合并复杂度很优秀,粘一发题解就跑,然而我在考场上觉得用真栈没什么必要,然后就打的链表模拟栈,链表记录某个元素在它和它的祖先链组成的单调栈中的上一个元素是谁。显然这样可以避免某些重复的情况,然后就可以用父亲更新儿子,显然答案的最优决策点是它的祖先链上在坐标系上形成的下凸包上离他最近的点,然后就用父亲的信息,一直往前跳就行了。但是考场上不会证复杂度,好像单调栈是$O(n)$的,好像可过??然后就死了。其实是一条链上$O(n)$然而精心构造的数据可能卡爆,考完突然被yxm提醒一下这个可以倍增。然后就A了。

     

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=200020,inf=1e9;
    int p[N],f[N],c[N];
    struct tree{int l,r,w,i,m;}tr[N*4];
    inline int rd()
    {
        int s=0,w=1;
        char cc=getchar();
        for(;cc<'0'||cc>'9';cc=getchar()) if(cc=='-')w=-1;
        for(;cc>='0'&&cc<='9';cc=getchar()) s=(s<<3)+(s<<1)+cc-'0';
        return s*w;
    }
    void build(const int k,const int l,const int r)
    {
        if(l==r)
        {
            tr[k].w=inf;
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);build(k<<1|1,mid+1,r);
    }
    int query(const int k,const int x,const int y,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==x&&r==y) return tr[k].i;
        if(y<=mid) return query(k<<1,x,y,l,mid);
        else if(x>mid) return query(k<<1|1,x,y,mid+1,r);
        return max(query(k<<1,x,mid,l,mid),query(k<<1|1,mid+1,y,mid+1,r));
    }
    int ask(const int k,const int x,const int y,const int i,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==r)
        {
            if(tr[k].i<i) return inf;
            return tr[k].w;
        }
        if(y<=mid) return ask(k<<1,x,y,i,l,mid);
        else if(x>mid) return ask(k<<1|1,x,y,i,mid+1,r);
        if(i>tr[k<<1|1].i) return ask(k<<1,x,mid,i,l,mid);
        const int rmax=query(k,mid+1,y,l,r);
        return min(ask(k<<1,x,mid,rmax,l,mid),ask(k<<1|1,mid+1,y,i,mid+1,r));
    }
    void updata(const int k){tr[k].i=max(tr[k<<1].i,tr[k<<1|1].i);}
    void add(const int k,const int id,const int i,const int l,const int r)
    {
        const int mid=l+r>>1;
        if(l==r)
        {
            tr[k].i=i;
            tr[k].w=f[i];
            return;
        }
        if(id<=mid) add(k<<1,id,i,l,mid);
        else add(k<<1|1,id,i,mid+1,r);
        updata(k);
    }
    int main()
    {
        const int n=rd();
        for(register int i=1;i<=n;i++) p[i]=rd();
        for(register int i=1;i<=n;i++) c[i]=rd();
        build(1,1,n+1);
        memset(f,0x3f,sizeof(f));
        f[0]=0;add(1,1,0,1,n+1);
        for(register int i=1;i<=n;i++)
        {
            const int maxi=0;
            f[i]=ask(1,1,p[i]+1,0,1,n+1)+c[i];
            add(1,p[i]+1,i,1,n+1);
        }
        register int ans=0x7fffffff,maxi=0;
        for(register int i=n;i>=1;i--)
        {
            if(p[i]>maxi)
            {
                ans=min(ans,f[i]);
                maxi=p[i];
            }
        }
        printf("%d
    ",ans);
    }
    /*
    g++ -std=c++11 1.cpp -o 1
    ./1
    5
    3 1 4 5 2
    3 4 3 4 1
    */
    4179ms
  • 相关阅读:
    paip.提升用户体验c++ 右键菜单以及socket接口
    paip. 'QObject::QObject(const QObject&)' is private问题的解决.
    paip.ollydbg 设置c++ qt API断点总结
    paip.提升用户体验c++ qt自定义窗体(1)标题栏的绘制
    paip.提升用户体验c++ QPushButton按钮控件透明以及不规则按钮以及 鼠标越过动态设置
    paip.c++ static 变量的定义以及使用...
    paip.c++ gcc 不能捕获exception异常的解决
    paip.pyqt python qt 最新版本环境最佳实践
    paip.提升用户体验c++ QLabel标签以及QLineEdit文本框控件透明 设置
    paip.c++ 宏的展开调试.
  • 原文地址:https://www.cnblogs.com/starsing/p/11371308.html
Copyright © 2020-2023  润新知