• 2019-8-9 考试总结


    A. 建设城市

    很熟悉的题面,和"那一天我们许下约定"差不多。

    $n^2$暴力很好想,$70$分也很好拿。

    但是没拿到。。

    正解是个容斥。

    用总的方案数减去不合法的方案数。

    不合法的也就是建设队大于等于$k+1$的。

    然后就容斥。

    $ans=C_{m-1}^{n-1}-sum limits_{i=1}^{m-ik-1>=0} (-1)^iC_n^i imes C_{m-ik-1}^{n-1}$。

    左边那个式子是个挡板,不考虑$k$的限制,每个城市至少有$1$的方案数。

    右边是个容斥,表示至少$i$个城市不合法的方案数。

    从$m$个建设队中选出$ik$个给$i$个城市,然后每个城市再分$1$,最后的那些随便分。

    在用一个挡板法。

    所以最后$C$的底数是$m-ik-n+n-1$,也就是$m-ik-1$。

    然后再乘一个$C_n^i$。

    就是这个式子。

    丑陋的代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define Maxn 10000050
    #define Reg register
    #define mod 998244353
    #define int long long
    #define _max(x,y) ((x)>(y)?(x):(y))
    #define C(x,y) (((x)<(y))?0:(fac[x]*inv[y]%mod*inv[(x)-(y)]%mod))
    using namespace std;
    int n,m,k,fac[Maxn],inv[Maxn],lss[Maxn];
    signed main()
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        fac[0]=inv[0]=fac[1]=inv[1]=lss[1]=1;
        if(n>m) printf("0");
        else
        {
            for(Reg int i=2;i<=m;++i)
            {
                fac[i]=fac[i-1]*i%mod;
                lss[i]=(mod-mod/i)*lss[mod%i]%mod;
                inv[i]=inv[i-1]*lss[i]%mod;
            }
            int ans=C(m-1,n-1);
            for(Reg int i=1,cur;i<=n;++i)
            {
                if(m-i*k-1<0) break;
                cur=(i&1)?-1:1;
                ans=(ans+cur*C(n,i)%mod*C(m-i*k-1,n-1)%mod+mod)%mod;
            }
            printf("%lld",(ans+mod)%mod);
        }
        return 0;
    }
    View Code

    B. 轰炸行动

    正解:

    $Tarjan$缩$scc$,然后跑拓扑找最长链。

    好吧,当时想到了$Tarjan$和拓扑,

    没想到要找最长链。。

    这个题只要找最长链的节点个数就可以了。

    因为每一条链上的点都要一个一个炸。

    丑陋的代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #define Maxn 10000050
    #define Reg register
    #define int long long
    #define _min(x,y) ((x)<(y)?(x):(y))
    #define _max(x,y) ((x)>(y)?(x):(y))
    using namespace std;
    int n,m,tot=0,top=0,fir[Maxn],fic[Maxn];
    int cnt,indx,low[Maxn],dfn[Maxn],stack[Maxn],ins[Maxn],bel[Maxn],sum[Maxn];
    int du[Maxn],dep[Maxn];
    struct Tu {int st,ed,next;} lian[Maxn],liap[Maxn];
    void add(int x,int y)
    {
        lian[++tot].st=x;
        lian[tot].ed=y;
        lian[tot].next=fir[x];
        fir[x]=tot;
        return;
    }
    void adp(int x,int y)
    {
        liap[++top].st=x;
        liap[top].ed=y;
        liap[top].next=fic[x];
        fic[x]=top;
        ++du[y];
        return;
    }
    void tarjan(int x)
    {
        low[x]=dfn[x]=++indx;
        stack[++stack[0]]=x; ins[x]=1;
        for(Reg int i=fir[x];i;i=lian[i].next)
        {
            if(!dfn[lian[i].ed])
            {
                tarjan(lian[i].ed);
                low[x]=_min(low[x],low[lian[i].ed]);
            }
            else if(ins[lian[i].ed])
                low[x]=_min(low[x],dfn[lian[i].ed]);
        }
        if(low[x]==dfn[x])
        {
            ++cnt;
            while(stack[stack[0]]!=x)
            {
                bel[stack[stack[0]]]=cnt;
                ins[stack[stack[0]--]]=0;
            }
            bel[stack[stack[0]]]=cnt;
            ins[stack[stack[0]--]]=0;
        }
        return;
    }
    void topsort()
    {
        queue<int> q; int p=1;
        for(Reg int i=1;i<=cnt;++i)
        {
            if(!du[i])
            {
                q.push(i); dep[i]=sum[i];
                p=_max(p,dep[i]);
            }
        }
        while(!q.empty())
        {
            int x=q.front(); q.pop();
    //        cout<<x<<' '<<sum[x]<<' '<<dep[x]<<endl;
            p=_max(p,dep[x]);
            for(Reg int i=fic[x];i;i=liap[i].next)
            {
                --du[liap[i].ed];
                dep[liap[i].ed]=_max(dep[liap[i].ed],dep[x]+sum[liap[i].ed]);
                if(du[liap[i].ed]==0)
                {
                    q.push(liap[i].ed);
                }
            }
        }
        printf("%lld",p);
        return;
    }
    signed main()
    {
    //    freopen("text.in","r",stdin);
        indx=cnt=tot=top=0;
        scanf("%lld%lld",&n,&m);
        for(Reg int i=1,x,y;i<=m;++i)
        {
            scanf("%lld%lld",&x,&y);
            add(x,y);
        }
        for(Reg int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
        for(Reg int i=1;i<=n;++i)
        {
            ++sum[bel[i]];
    //        cout<<bel[i]<<' ';
        }
    //    cout<<endl;
        for(Reg int i=1;i<=tot;++i)
            if(bel[lian[i].st]!=bel[lian[i].ed])
                adp(bel[lian[i].st],bel[lian[i].ed]);
        topsort();
        return 0;
    }
    View Code

    C. 石头剪刀布

    总结:

    看到$T1$基本上是原题,而且我又什么都想不起来,心态近乎爆炸。

    最后连$n^2$暴力的分都没拿到。

    说是低错,就是没水平。。。

    $T2$用$Tarjan$缩$scc$很好想。

    拓扑排序找最长链这比较难想。

    考试一碰见图论和方案计数$dp$和概率期望就死了。

    $T3$用玄学$dfs$和特判水到$20$分。

    $T1$和$T2$就惨了。

    最后$20+0+20=40$。

    没什么水平。。。

  • 相关阅读:
    Java 数据库操作oracle增删改查,通用封装基于hashmap
    Python 自动化paramiko操作linux使用shell命令,以及文件上传下载linux与windows之间的实现
    Java利用 ganymedssh2build.jar来上传文件到linux以及下载linux文件以及执行linux shell命令
    Java Calendar and SimpleDateFormat 时间模块
    Java 读取properties
    Java java httpclient4.5 进行http,https通过SSL安全验证跳过,封装接口请求 get,post(formdata,json)封装,文件上传下载
    Python 基于request库的get,post,delete,封装
    更法第一 (zz)
    北京将投资707亿元建三条地铁新线 (zz.IS2120@BG57IV3)
    fgetws 讀取Unicode文件 (zz.IS2120@BG57IV3)
  • 原文地址:https://www.cnblogs.com/Milk-Feng/p/11327447.html
Copyright © 2020-2023  润新知