• 【摸鱼on牛客】2020ICPC 小米 网络选拔赛第一场


    2020ICPC 小米 网络选拔赛第一场

    前言

    前面三个多小时只有两个人在肝题,太艰难了QAQ
    好在还是摸进决赛了,and充电宝++(* ̄︶ ̄)

    训练情况


    训练时出现的问题

    前期的问题还是签到的速度,从10min+才开始有过题,跟第一梯队还是有一定差距。。
    中期很顺利,几乎没有罚时。。
    后期在开构造题G的时候没有想清楚就交了。还是抱有侥幸心理啊。。。然后罚时就炸了。后面是真的慌了,连个最基础的线段树都出了好多错。
    以后写题还是得想清楚再交,暴力的算法最多交一发试试水。。

    部分题解

    G Tree Projection

    链接

    Tree Projection

    题意

    给定一颗(n)个点的无根树的某个拓扑序A和DFS序B,要求求出一颗符合的树。(1leq n leq 2 imes 10^5)

    题解

    (A_1)(B_1)相等,那么直接让其余所有点连向(A_1),显然这是合理的。
    然后考虑不相等的情况,这个时候我们先找到(B_1)(A)中的位置,然后在这之前的(A)中的数显然在(B_1)为根的树种在同一颗子树中,我们可以在(B)中找到这颗子树占据的范围,然后根据这范围我们能将问题分成两个部分:
    1.一部分有(B_1),这部分还包含不在那颗子树内的其他点,找到这些点在A中的位置后,得到新的子问题,这个问题中符合(A_1=B_1)
    2.这部分只包含之前分出来的子树,重复上面的操作递归即可。
    按照上面的操作,我们发现这个问题是一定有解的。
    我刚开想到这些后直接写,然后T飞了。。
    如何在保证复杂度的情况下完成上面的操作?
    只需要开一颗线段树维护一下前(i)个A中的点在B中所需的范围,在删B中的点时支持单点修改即可。
    在B中删点时将指针从两端往中间扫,只扫到要删的点,这样每个点只扫到删掉一次,就能(O(nlogn))了。

    (Code)

    #include<bits/stdc++.h>
    #define LL long long
    #define LD double
    using namespace std;
    const double PI=acos(-1);
    const int INF=1e9;
    const int N=2e5+10;
    int n;
    int cnt=0;
    int u[N],v[N];
    int w[N];
    int a[N],b[N],t[N],byc[N],kcz[N];
    struct node{
        int l,r;
        int mx,mn;
    }d[N<<2];
    #define ls i<<1
    #define rs i<<1|1
    void build(int l,int r,int i){
        d[i].l=l;d[i].r=r;
        if(l==r){
            d[i].mn=byc[l];
            d[i].mx=byc[l];
            return;
        }
        int mid=l+r>>1;
        build(l,mid,ls);
        build(mid+1,r,rs);
        d[i].mn=min(d[ls].mn,d[rs].mn);
        d[i].mx=max(d[ls].mx,d[rs].mx);
    }
    void C(int i,int r){
        if(d[i].l==d[i].r){
            d[i].mx=-1;
            d[i].mn=n+1;
            return;
        }
        if(r<=d[ls].r) C(ls,r);
        else C(rs,r);
        d[i].mn=min(d[ls].mn,d[rs].mn);
        d[i].mx=max(d[ls].mx,d[rs].mx);
    }
    int MN,MX;
    void ask(int i,int r){
        if(d[i].l==d[i].r){
            MN=min(d[i].mn,MN);
            MX=max(d[i].mx,MX);
            return;
        }
        if(r<=d[ls].r) ask(ls,r);
        else {
            MN=min(MN,d[ls].mn);
            MX=max(MX,d[ls].mx);
            ask(rs,r);
        }
        return;
    }
    void get(int l,int r){
        if(l>=r) return;
        if(l+1==r){
            ++cnt;
            u[cnt]=b[l];
            v[cnt]=b[r];
            return;
        }
        if(a[1]==b[l]){
            for(int i=l+1;i<=r;++i){
                ++cnt;u[cnt]=b[l];v[cnt]=b[i];
            }
            return;
        }
        int x=kcz[b[l]];
        MN=r+1;MX=l-1;
        ask(1,x-1);
        for(int i=l;i<MN;++i){
            if(i>l){
                ++cnt;u[cnt]=b[l];v[cnt]=b[i];
            }
            C(1,kcz[b[i]]);
        }
        for(int i=MX+1;i<=r;++i){
            if(i>l){
                ++cnt;u[cnt]=b[l];v[cnt]=b[i];
            }
            C(1,kcz[b[i]]);
        }
        
        ++cnt;u[cnt]=b[l];v[cnt]=b[MN];
        get(MN,MX);
    }
    
    int main(){
        scanf("%d",&n);
        int x;
        for(int i=1;i<=n;++i) {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;++i){
            scanf("%d",&b[i]);kcz[b[i]]=i;
        }
    
        for(int i=1;i<=n;++i){
            byc[i]=kcz[a[i]];
        }
        build(1,n,1);
        for(int i=1;i<=n;++i){
            kcz[a[i]]=i;
        }
        get(1,n);
        puts("YES");
        for(int i=1;i<=cnt;++i){
            printf("%d %d
    ",u[i],v[i]);
        }
        return 0;
    }
    

    K Sqrt Approaching

    链接

    Sqrt Approaching

    题意

    给出正整数A,B,n,要求C,D满足(A/B<C/D<n^{0.5})(1leq A,B leq 10^{99990}),(2leq n leq 10^{9})

    题解

    原题面恶心的很。。但式子稍微推一下就变成上面那个题意啦。。
    然后我就不会做了QAQ。不管怎么搞总是有很大误差的说。
    然后题解神奇的给了个通解但没有给出证明QAQ(而且我也不会证,那这东西就当是公式记住吧)
    C=(n+1)A+2nB; D=2A+(n+1)B

    (Code)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const LL P=998244353;
    const int N=2e5+100;
    const double PI=acos(-1);
    
    char s[N];
    LL a[N],b[N],c[N],d[N];
    int L=100000,len;
    LL n;
    int main(){
        int f;
        for(int i=0;i<=100000;++i) a[i]=b[i]=c[i]=d[i]=0;
        scanf("%s",s+1);len=strlen(s+1);
        int ca=-1;
        for(int i=len;i>=1;--i)a[++ca]=s[i]-'0';
        scanf("%s",s+1);len=strlen(s+1);
        int cb=-1;
        for(int i=len;i>=1;--i)b[++cb]=s[i]-'0';
        scanf("%lld",&n);
        for(int i=0;i<=100000;++i){
            c[i]=(n+1)*a[i]+(LL)2*n*b[i];
            d[i]=(LL)2*a[i]+(n+1)*b[i];
        }
        for(int i=0;i<=100000;++i){
            if(c[i]>=(LL)10){
                c[i+1]+=c[i]/10;
                c[i]=c[i]%(LL)10;
            }
            if(d[i]>=(LL)10){
                d[i+1]+=d[i]/10;
                d[i]=d[i]%(LL)10;
            }
        }
        
        f=0;
        for(int i=100000;i>=0;--i){
            if(c[i]>0) f=1;
            if(f) printf("%d",c[i]);
        }
        puts("");
        f=0;
        for(int i=100000;i>=0;--i){
            if(d[i]>0) f=1;
            if(f) printf("%d",d[i]);
        }
        puts("");
        return 0;
    }
    

    H Grouping

    链接

    Grouping

    题意

    将2n个数分成n对,每对的价值是两数的差的绝对值,一种分法的价值是每对的价值的方差,问所有分法的期望价值,对998244353取模。(1leq n leq 10^{5})

    题解

    这题式子其实挺好推的,但是我队开题并不积极,基本都是跟榜。
    然后这题基本没几个队过,就没开这题。
    现在看来并不难啊。。血亏
    过程直接放题解的截图吧。。

    (Code)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const LL P=998244353;
    const int N=2e5+100;
    const double PI=acos(-1);
    LL ans;
    LL n;
    LL a[N],s[N],s2[N],g[N],f[N];
    LL T[N];
    LL qpow(LL x,LL y){
        LL re=1;
        while(y){
            if(y&1) re=re*x%P;
            x=x*x%P;y>>=1;
        }
        return re;
    }
    int main(){
        LL res;
        scanf("%lld",&n);
        if(n==1){
            puts("0");
            return 0;
        }
        for(int i=1;i<=n+n;++i){
            scanf("%lld",&a[i]);
        }
        sort(a+1,a+1+n+n);
        for(LL i=1;i<=n+n;++i){
            s[i]=(s[i-1]+a[i])%P;
            s2[i]=(s2[i-1]+a[i]*a[i])%P;
            g[i]=(i-1)*a[i]%P*a[i]%P;
            g[i]=(g[i]+s2[i-1])%P;
            g[i]=(g[i]-(LL)2*a[i]*s[i-1])%P;
            g[i]+=g[i-1];
            g[i]=(g[i]%P+P)%P;
            f[i]=(i-1)*a[i]%P-s[i-1];
            f[i]+=f[i-1];
            f[i]=(f[i]%P+P)%P;
        }
        ans=g[n+n];
        res=n*(n+n-1)%P;
        ans=ans*qpow(res,P-2)%P;
        T[0]=T[1]=1;
        for(LL i=2;i<=n;++i) T[i]=T[i-1]*(i+i-1)%P;
        LL val=g[n+n]*T[n-1]%P;
        LL u=f[n+n]*f[n+n]%P,v;
        for(LL i=1;i<=n+n;++i){
            v=0;
            v+=(i-1)*a[i]%P-s[i-1];
            v+=(s[n+n]-s[i])-(n+n-i)*a[i]%P;
            v=(v%P+P)%P;
            v=v*v%P;
            u-=v;
        }
        u=((u+g[n+n])%P+P)%P;
        u=u*T[n-2]%P;
        val=(val+u)%P*qpow(T[n]*n%P*n%P,P-2)%P;
        ans=(ans-val+P)%P;
        cout<<ans<<endl;
        return 0;
    }
    /*
    2
    2 2 3 4
    748683265
    */
    
  • 相关阅读:
    Myeclipse 安装svn插件
    Http状态码详解
    myeclipse中的js文件报错
    eclipse 反编译插件安装
    ecshop绕过验证码暴力破解
    Myeclipse中全部文件设置成UTF-8
    WampServer phpadmin apache You don't have permission to access
    如何在Win8系统上建立WIFI热点
    记录远程桌面登录者的IP和MAC
    数据库总结
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/13894150.html
Copyright © 2020-2023  润新知