zoukankan      html  css  js  c++  java
  • 8.12模拟赛

    T1.码灵鼠

    手推f[2],f[3]可以发现f[i]=i-1

    给出归纳证明:

    为什么E(ai)+E(aj)==2E(ai)?因为i和j是相互独立的。

    记得long long

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    inline long long rd(){
        long long ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    long long n;
    
    int main(){
        n=rd();
        for(int i=1;i<=n;i++){
            long long x=rd();
            printf("%lld
    ",x+1ll);
        }
    }
    View Code

    T2.So many prefix?

    感觉是kmp,可是发现状态叠状态,很难做,暴力走人了

    正解是这样的,那些重叠的状态,实际上i的上一个重叠位置就是fail[i],因此f[i]可以由f[fail[i]]转移来,这样就解决了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=200005;
    
    char s[MAXN];
    int fail[MAXN];
    long long f[MAXN];
    
    int main(){
        scanf("%s",s+1);
        int lens=strlen(s+1);
        for(int i=2,j=0;i<=lens;i++){
            while(j>0&&s[i]!=s[j+1]) j=fail[j];
            if(s[i]==s[j+1]) j++;
            fail[i]=j;
        }
        long long ans=0;
        for(int i=1;i<=lens;i++) f[i]=f[fail[i]]+1ll*(!(i&1));
        for(int i=1;i<=lens;i++) ans+=f[i];
        cout<<ans;
    }
    View Code

    T3.Travel

    之前A组的题,并没有写,考场上现推有点难受

    考虑把R降序排序,从大到小枚举Ri,保证了上边界递减,然后从小到大枚举L,只考虑R大于Ri的部分,这样保证右边界一定为Ri,由于L是递增的,所以可以一条一条加边,第一次使得1和n连通便是L的最小值,这时候的L和Ri便是一组解,更新即可。

    由于是从大到小枚举的R,所以每次更新,最后便是字典序最小的解。

    复杂度O(αn^2)

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=1024;
    const int M=2048*4;
    
    int n,m;
    
    int frm[M],to[M],L[M],R[M],idr[M],idl[M];
    
    bool cmpr(int x,int y){return R[x]>R[y];}
    bool cmpl(int x,int y){return L[x]<L[y];}
    
    int fa[MAXN];
    void seti(){for(int i=1;i<=n;i++) fa[i]=i;}
    int fnd(int x){return x==fa[x]?x:fa[x]=fnd(fa[x]);}
    void cat(int x,int y){
        x=fnd(x);y=fnd(y);
        if(x==y) return;
        fa[y]=x;
    }
    
    int solve(int down){
        for(int i=1;i<=m;i++){
            int k=idl[i];
            if(R[k]<down) continue;
            cat(frm[k],to[k]);
            if(fnd(1)==fnd(n)) return L[k];
        }
        return -1;
    }
    
    int ansl=0,ansr=-1;
    
    int main(){
        n=rd();m=rd();
        int x,y,l,r;
        for(int i=1;i<=m;i++){
            frm[i]=rd();to[i]=rd();
            L[i]=rd();R[i]=rd();
            idl[i]=i;idr[i]=i;
        }
        sort(idl+1,idl+1+m,cmpl);
        sort(idr+1,idr+1+m,cmpr);
        int tmp=0;
        for(int i=1;i<=m;i++){
            seti();int v=idr[i];
            tmp=solve(R[v]);
            if(tmp==-1) continue;
            if(R[v]-tmp<ansr-ansl) continue;
            if(R[v]-tmp>=ansr-ansl) {
                ansr=R[v];
                ansl=tmp;
                continue;
            }
        }
        if(ansr==-1) return puts("0"),0;
        printf("%d
    ",ansr-ansl+1);
        for(int i=ansl;i<=ansr;i++) printf("%d ",i);
        return 0;
    }
    View Code

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9464296.html

  • 相关阅读:
    sh脚本学习笔记
    idea常见快捷键
    linux操作命令笔记
    【题解】[国家集训队]圈地计划
    【题解】[国家集训队]happiness
    【题解】小M的作物
    cpu的MMU
    socat命令
    strace命令
    Linux的文件描述符
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9464296.html
Copyright © 2011-2022 走看看