• Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined)


    C题卡了好久,A掉C题之后看到自己已经排在好后面说实话有点绝望,最后又过了两题,总算稳住了。

    AC:ABCDE Rank:191 Rating:2156+37->2193

    A.Oath of the Night's Watch

    题目大意:给定N个数,求有多少个数存在严格比它大的数和严格比它小的数。(N<=100,000)

    思路:阅读能力训练+手速,排序一遍就没了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char B[1<<26],*S=B,C;int X;
    inline int read()
    {
        while((C=*S++)<'0'||C>'9');
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X;
    }
    #define MN 100000
    int a[MN+5];
    int main()
    {
        fread(B,1,1<<26,stdin);
        int n=read(),i,ans=0;;
        for(i=1;i<=n;++i)a[i]=read();
        sort(a+1,a+n+1);
        for(i=1;i<=n;++i)if(a[i]!=a[1]&&a[i]!=a[n])++ans;
        printf("%d",ans);
    }

    B.Code For 1

    题目大意:一开始有一个数N,每次能把一个大于1的数x拆成x/2,x%2,x/2(除法向下取整),拆到不能拆时停止,问最后拆出来的01序列的[l,r]中有几个1。(0<=n<2^50,0<=r-l<=10^5,r>=1,l>=1,r不超过最终拆出序列的长度)

    思路:可以logN预处理出N能拆出的所有数最后拆完的长度,然后分治,每次把[l,r]分到拆出的三段里,最后复杂度大约是O((r-l)logN)。

    #include<iostream>
    #include<map>
    #define ll long long
    using namespace std;
    map<ll,ll> mp;
    int ans;
    ll cal(ll x)
    {
        if(mp[x])return mp[x];
        return mp[x]=cal(x>>1)+cal(x&1)+cal(x>>1);
    }
    void work(ll x,ll l,ll r)
    {
        if(x<2){if(x)++ans;return;}
        ll mid=mp[x>>1];
        if(r<=mid)work(x>>1,l,r);
        else if(l<=mid)work(x>>1,l,mid);
        if(l<=mid+1&&r>=mid+1)work(x&1,1,1);
        if(l>mid+1)work(x>>1,l-mid-1,r-mid-1);
        else if(r>mid+1)work(x>>1,1,r-mid-1);
    }
    int main()
    {
        ll n,l,r;
        cin>>n>>l>>r;
        mp[0]=mp[1]=1;cal(n);
        work(n,l,r);
        cout<<ans;
    }

    C.Jon Snow and his Favourite Number

    题目大意:给定N,k,x和N个数,每次操作把N个数排序,排在奇数位的异或上x,重复k次操作,问最终序列的最大值和最小值。(1<=N<=10^5,0<=k<=10^5,0<=x<=10^3,序列中元素小等于10^3)

    思路:一开始往奇怪的方向想,例如做几次操作后就会开始循环,然后考虑暴力做几次操作,想优化一下暴力,发现序列元素特别小,可以计数排序……然后猛然发现只要存1024种元素的个数每次分下奇偶暴力做就可以了……并不需要什么结论,而且时限有4s,应该比较科学。复杂度O(N+1024k)。另外cf机子真的快,理论上上亿次运算最慢的只跑了200ms+(PP的时候显示的233ms,是不是被嘲讽了?)(另外一提,我家机子要4秒……)。

    #include<cstdio>
    #include<cstring>
    char B[1<<26],*S=B,C;int X;
    inline int read()
    {
        while((C=*S++)<'0'||C>'9');
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X;
    }
    #define MN 100000
    int a[2][1030];
    int main()
    {
        fread(B,1,1<<26,stdin);
        int n,k,x,i,p,q,l;
        n=read();k=read();x=read();
        for(i=1;i<=n;++i)++a[0][read()];
        for(p=1,q=0;k--;p^=1,q^=1)
        {
            memset(a[p],0,sizeof(a[p]));
            for(i=l=0;i<1024;++i)
            {
                a[p][i]+=a[q][i]+l>>1;
                a[p][i^x]+=a[q][i]+(l^1)>>1;
                l^=a[q][i]&1;
            }
        }
        for(i=1024;i--;)if(a[q][i])break;printf("%d ",i);
        for(i=0;i<1024;++i)if(a[q][i])break;printf("%d",i);
    }

    D.Jon and Orbs

    题目大意:k种数,每次取会等概率取到其中一种,q次询问,每次给出一个pi,要求求出最少取几次后每种数至少取到一次的概率至少pi/2000(题目中怕你被卡精度写的(pi-eps)/2000,eps<1e-7,好良心啊)(1<=k,q,pi<=1000)。

    思路:概率DP,f[i][j]表示取i个取到j种不同元素的概率,再取一个有j/k的概率取到取过的,有(k-j)/k的概率取到没取过的,初始化f[0][0]=1,然后递推就可以了。发现最大的数据k=1000,pi=1000时只要取7000多个,然后随便做了。(好像以前见过这道题,当时naive怎么想都不会,现在已经变成水题了……)

    #include<cstdio>
    char B[1<<26],*S=B,C;int X;
    inline int read()
    {
        while((C=*S++)<'0'||C>'9');
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X;
    }
    #define MN 1000
    double f[MN*10+5][MN+5];
    int main()
    {
        fread(B,1,1<<26,stdin);
        int k=read(),q,i,j,x;
        for(f[1][1]=i=1;i<=10000;++i)for(j=1;j<=i&&j<=k;++j)
        {
            f[i+1][j]+=f[i][j]*j/k;
            f[i+1][j+1]+=f[i][j]*(k-j)/k;
        }
        for(q=read();q--;)
        {
            x=read();
            for(i=1;i<=10000;++i)if(f[i][k]>=(x-1e-7)/2000)break;
            printf("%d
    ",i);
        }
    }

    E.Game of Stones

    题目大意:N堆石子,每堆石子有si个,两个玩家轮流取石子,每次可以取走一堆中任意正整数个,不能取的算输,有一个限制条件是同一堆中不能两次取走相同数量的石子,求最优策略下先手必胜还是必败。(N<=1,000,000,1<=si<=60)。

    思路:博弈论的题我不是很熟悉,看了几眼就先去看F了,想了很久F不会又滚回来做E,幸好还模糊记得博弈论那套理论,只要求出每一堆的SG值全部异或起来就可以了。发现si<=60很可怕,能不能打打表之类的?想了想,每堆的SG值好像就是最多能拆出几种不同的正整数……因为可以把拆出的最大的k种删掉得到SG值小k的情况而对后面没有影响。得出这个结论的我是巨虚无比的,因为我只要O(maxsi)就能求出各种si的SG值,而maxsi只有60……怀着试试和这个WA了反正我也想不出其他做法的心态交了一发,结果cf当时评测队列好像出了点问题,没即时显示,我只好继续肝F,肝着突然发现这题PP了,最后也AC了,不知道这个60的数据范围到底是哪里冒出来的啊?最终复杂度O(N+maxsi)。

    #include<cstdio>
    char B[1<<26],*S=B,C;int X;
    inline int read()
    {
        while((C=*S++)<'0'||C>'9');
        for(X=C-'0';(C=*S++)>='0'&&C<='9';)X=(X<<3)+(X<<1)+C-'0';
        return X;
    }
    int f[61];
    int main()
    {
        fread(B,1,1<<26,stdin);
        int n=read(),i,j,k,ans=0;
        for(i=1;i<=10;++i)
            for(j=i*(i+1)/2;j<=60&&j<(i+1)*(i+2)/2;++j)f[j]=i;
        for(i=1;i<=n;++i)ans^=f[read()];
        puts(ans?"NO":"YES");
    }

    F.Barrels and boxes

    题目大意:N个A物品,M个B物品,把所有A物品堆成若干堆,所有B物品堆成若干堆,相间地排成一列(如ABAB、BAB等)求每堆B物品中B物品数量都超过H的概率(对1e9+7取模)。(N,M,H<=100,000,N+M>0)

    思路:做的时候看错题意,看题解的时候才发现,无比尴尬(我以为是求至少一堆超过H),然后才发现是SB题。题目相当于把A和B随意排列,然后相邻的同种物品并成一堆,先把A排开,然后相当于有N+1个空位给我们塞B,枚举塞几堆B,每堆B我们先强制扣掉H,直接排列组合计算,方案数即为Σ(C(M-i*H-1,i-1)*C(N+1,i)),总方案数令H=0再算一遍就能知道概率了,注意特判M=0。交的第一发阶乘只预处理到100,000然后WA了,发现有个N+1,要多预处理一位……

    #include<cstdio>
    #define MN 100001
    #define MOD 1000000007
    int f[MN+5],r[MN+5];
    int C(int n,int m){return 1LL*f[n]*r[m]%MOD*r[n-m]%MOD;}
    int inv(int x)
    {
        int t=x,y=MOD-3;
        for(;y;t=1LL*t*t%MOD,y>>=1)if(y&1)x=1LL*x*t%MOD;
        return x;
    }
    int cal(int n,int m,int p)
    {
        if(!m)return 1;
        int r=0,i;
        for(i=1;i<=n+1&&i*(p+1)<=m;++i)
            r=(r+1LL*C(m-i*p-1,i-1)*C(n+1,i))%MOD;
        return r;
    }
    int main()
    {
        int n,m,p,i,x=0,y=0;
        for(f[0]=i=1;i<=MN;++i)f[i]=1LL*f[i-1]*i%MOD;
        for(r[i=MN]=inv(f[MN]);i--;)r[i]=1LL*r[i+1]*(i+1)%MOD;
        scanf("%d%d%d",&n,&m,&p);
        printf("%d",1LL*cal(n,m,p)*inv(cal(n,m,0))%MOD);
    }
  • 相关阅读:
    【IOS】ObjectC 中的Selector 概念
    iOS开发笔记 3、iOS基础
    iOS开发笔记 2、Cocoa简明
    iOS开发笔记 4、iOS中的Cocoa、设计模式等
    iOS开发笔记 5、开发工具Xcode,Inteface Builder
    iOS开发笔记 8、真机调试和发布软件
    移动App如何收费的模式和步骤分析
    带滚动条的二级黑色竖直菜单(CSS实现)
    很是动感的一款js伸缩、关闭菜单
    JS实现类似腾讯QQ折叠菜单
  • 原文地址:https://www.cnblogs.com/ditoly/p/CF399.html
Copyright © 2020-2023  润新知