zoukankan      html  css  js  c++  java
  • 5.4

    考中:

    t1看了一眼,感觉像淀粉质,思考了一下,发现可以,而且代码难度也不高,在继续看和写代码之间选择了写代码,然后,果不其然,我又双叒叕想了个假算法,心塞,看了看暴力,只会30分,开始写30分的,写完以后,又思考了一下原来的错误做法,发现其实没错,又看了一眼题面,然后,果不其然,我又双叒叕看错题了,呵呵,于是看t2,很好,有30分,然后看t3,有60分,算了算,有110分,感觉还行,代码都还好,于是找看了一圈,发现没有老师,找zyz商量了一下,于是回寝室了

    t1:

    10分,直接枚举

    30分,直接dfs一下,上组合数

    剩下的待填

    t2:

    60分:直接做(应该没有人不会吧,我就不会)

    截止时间 i 的答案ans 应当是满足 j*k >= 截止时间在 k 及以前的订单数量 k=1,2,……i  的最小的 j 

    100分:待填

    t3:

    50分:bitset搞一下就完了

    100分:

    考虑50分的瓶颈,在于无法直接根据某些东西快速求出后面的点集,考虑拓扑的过程。

    所以我们考虑dfs序,显然是后序,容易发现:所以x可以走到的点其实是dfs后序在x前面的点,但这样我们会发现有不合法的点,不合法的点是dfs v 结束后,dfs 接下来的v得到的,所以翻转一下从x连出去的点,dfs后序同时<=x的点就可以刚好被加入答案了

    给的题解实际上更复杂了

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=300005,M=400000+5;
    struct er{
        int x,y,v;
    }dian[N];
    struct qw{
        int x,v;
    };
    int cmp(qw l,qw r)
    {
        return l.v<r.v;
    }
    vector<qw> next1[N];
    int ru_1[N],ru_2[N];
    void lian(int x,int y,int v)
    {
        next1[x].push_back((qw){y,v});
        ru_1[y]++;
        ru_2[y]++;
    }
    int dfn1[N],dfn2[N],tim;
    int rnk[N];
    void dfs_1(int x)
    {
        tim++;
        rnk[tim]=x;
        for(int i=0;i<next1[x].size();i++)
        {
            int v=next1[x][i].x;
            ru_1[v]--;
            if(!ru_1[v]) dfs_1(v);
        }
    }
    void dfs_2(int x)
    {
        tim++;
        rnk[tim]=x;
        for(int i=0;i<next1[x].size();i++)
        {
            int v=next1[x][i].x;
            ru_2[v]--;
            if(!ru_2[v]) dfs_2(v);
        }
    }
    int c[N],n;
    void add(int x,int v)
    {
        if(x==0) return;
        while(x<=n)
        {
            c[x]+=v;
            x+=x&-x;
        }
    }
    int query(int x)
    {
        int res=0;
        while(x)
        {
            res+=c[x];
            x-=x&-x;
        }
        return res;
    }
    int ans[N],f[N];
    int main()
    {
        freopen("souvenir.in","r",stdin);
        freopen("souvenir.out","w",stdout);
        int m;
        cin>>n>>m;
        int x,y;
        for(int i=1;i<=n;i++)
        scanf("%d %d %d",&dian[i].x,&dian[i].y,&dian[i].v);
        while(m--)
        {
            scanf("%d %d",&x,&y);
            if(dian[y].x>dian[x].x||dian[y].y>dian[x].y) lian(x,y,dian[y].x>dian[x].x);
            else lian(y,x,dian[x].x>dian[y].x);
        }
    //    for(int i=1;i<=n;i++) sort(next1[i].begin(),next1[i].end(),cmp);
        dfs_1(1);
        for(int i=1;i<=n;i++) dfn1[rnk[i]]=n-i+1;
        tim=0;
        for(int i=1;i<=n;i++) reverse(next1[i].begin(),next1[i].end());
        dfs_2(1);
        for(int i=1;i<=n;i++) dfn2[rnk[i]]=n-i+1;//图的拓扑序,不能直接dfs后面加tim++,应该等x的y全部遍历完才能把x丢进去 
        for(int i=n;i>=1;i--)
        {
            x=rnk[i];
            add(f[dian[x].v],-1);
            if(!f[dian[x].v]) f[dian[x].v]=dfn1[x];
            else f[dian[x].v]=min(f[dian[x].v],dfn1[x]);
            add(f[dian[x].v],1);
            ans[x]=query(dfn1[x]);//不能这里-1,ans+1,因为query统计的是颜色,而-1以后有的点会统计到自己的颜色,有的点不会 
        }
        for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
        return 0;
    }
    /*
    7 7
    1 1 1
    3 1 2
    1 2 1
    2 2 3
    3 3 4
    2 4 1
    3 4 2
    1 2
    1 3
    4 3
    5 2
    5 7
    4 6
    7 6
    */
  • 相关阅读:
    简单记事本 V0.5
    一次对webplayer的嗅探
    引用的DLL不能调试的问题
    软件:让人越懒越好
    如何设置mysql远程访问
    ASP.NET基础培训 Cookie的正确利用
    Mysql中新建和调用存储过程
    CentOS下mysql的中文编码问题
    mysmall.ini、mymedium.ini、mylarge.ini、myhuge.ini文件的作用
    创建自定义线程池
  • 原文地址:https://www.cnblogs.com/xsm098/p/14730318.html
Copyright © 2011-2022 走看看