• ETO的公开赛T5《猎杀蓝色空间号》题解


    这道题别看题面这么长,其实题意很简单

    就是让你求从起点开始的最长合法区间

    合法的要求有两个:兜圈子和直飞

    且这两个条件相互独立

    (也就是说兜圈子的末尾不会对下面可能出现的直飞造成影响)

    举个例子:

    1 2 3 2 1 5 4 3 8 9

    这个序列他的合法长度是8

    因为直飞是 5 4 3 8 9

    1是兜圈子的末尾,对直飞无影响

    这样看来,兜圈子比直飞优秀的多

    因为如果直飞的某段属于兜圈子

    那么把这一段归于兜圈子后对序列的合法性无影响

    但如果兜圈子的某段属于直飞,那归于直飞后

    剩下的这部分可能就不是兜圈子了

    所以我们先用manacher跑出回文区间

    用差分数组维护一下回文区间

     如果在回文区间内,则不考虑

    否则判断是否直飞即可

    只要确保完全符合,就记下来这个区间和这个区间的末尾值

    后面的就是贪心了

    最优情况自然是你选的那条正好是飞船所在

    飞船所在正好是最短的

    最坏情况是你最后一次选到的是最短的

    且这个位置是飞船所在

    几率我们会惊讶的发现其实是一样的

    排个序第二个也很好求

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rii register int i
    #define rij register int j 
    #define mod 19260817
    using namespace std;
    char s[200005],cp[200005];
    int p[200005],cd,t,n,ans,cnt,jl[105],cf[200005],lnt;
    char zcq1[200005];
    int zcq2[200005],m;
    void ycl()
    {
        int k=0;
        cp[k]=1;
        k++;
        for(rii=0;i<=cd-1;i++)
        {
            cp[k]='#';
            k++;
            cp[k]=s[i];
            k++;
        }
        cp[k]='#';
        k++;
        cd=k;
    }
    void manacher()
    {
        ycl();
        int mx=0;
        int last=0;
        for(rii=1;i<=cd-1;i++)
        {
            if(mx>i)
            {
                p[i]=min(p[2*last-i],mx-i);
            }
            else
            {
                p[i]=1;
            }
            while(cp[i+p[i]]==cp[i-p[i]]) 
            {
                p[i]++;
            }
            if(p[i]+i>mx)
            {
                mx=p[i]+i;
                last=i;
            }
        }
    }
    void cfs()
    {
        for(rii=1;i<=cnt;i++)
        {
            if(zcq2[i]>1)
            {
                cf[i-(zcq2[i])/2]++;
                cf[i+(zcq2[i])/2]--;
            }
        }
    }
    int yz()
    {
        int sl=0,pre=0,pd=0;
        for(rii=1;i<=cnt;i++)
        {
            sl+=cf[i];
            if(sl==0&&cf[i]>=0)
            {
                if(pre==0)
                {
                    pre=zcq1[i];
                    continue;
                }
                if(pd==0)
                {
                    if(zcq1[i]>pre)
                    {
                        pd=1;
                    }
                    else
                    {
                        if(zcq1[i]==pre)
                        {
                            pd=0;
                        }
                        else
                        {
                            pd=2;
                        }
                    }
                    pre=zcq1[i];
                    continue;
                }
                if(pd==1)
                {
                    if(pre>zcq1[i])
                    {
                        return i;
                    }
                    else
                    {
                        pre=zcq1[i];
                    }
                }
                if(pd==2)
                {
                    if(pre<zcq1[i])
                    {
                        return i;
                    }
                    else
                    {
                        pre=zcq1[i];
                    }
                }
            }
            else
            {
                pre=0;
            }
        }
        return cnt+1;
    }
    long long pw(long long ds,int ms)
    {
        long long res=1;
        while(ms!=0)
        {
            if(ms%2==1)
            {
                ms--;
                res*=ds;
                res%=mod;
            }
            else
            {
                ds*=ds;
                ds%=mod;
                ms/=2;
            }
        }
        return res;
    }
    bool cmp(int kl,int lk)
    {
        return kl<lk;
    }
    void sr()
    {
        memset(s,0,sizeof(s));
        memset(p,0,sizeof(p));
        memset(cf,0,sizeof(cf));
        for(rij=0;j<t;j++)
        {
            s[j]=getchar();
        }
        getchar();
        getchar();
    }
    void fz()
    {
        for(rij=2;j<=cd-1;j+=2)
        {
            cnt++;
            zcq1[cnt]=cp[j];
            zcq2[cnt]=p[j]-1;
        }
    }
    int main()
    {
        scanf("%d %d",&n,&t);
        scanf("%d ",&m);
        for(rii=1;i<=n;i++)
        {
               sr();
            cd=t;
            manacher();
            cnt=0;
            fz();
            cfs();
            int bnt=cnt;
            int ltt=yz();
            if(ltt==m+1)
            {
                lnt++;
                jl[lnt]=pw(zcq1[bnt],zcq1[bnt]);
            }
    //        printf("%d
    ",ans-1);
        }
        if(lnt==0)
        {
            cout<<"-1";
            return 0;
        }
        if(lnt==1)
        {
            cout<<jl[1]<<" "<<jl[1]<<" 1.00000000 1.00000000";
            return 0;
        }
        sort(jl+1,jl+lnt+1,cmp);
        int minx=jl[1];
    //    jl[1];
        int ant=1;
        long long js=0;
        for(rii=2;i<=lnt;i++)
        {
            if(jl[i]==minx)
            {
                ant++;
            }
            else
            {
                break;
            }
        }
        for(rii=2;i<=lnt;i++)
        {
            js+=jl[i];
        }
        js*=2;
        js+=minx;
        cout<<minx<<" "<<js<<" ";
        double kn=((1.0)*ant)/lnt;
        kn/=lnt;
        printf("%.8lf %.8lf",kn,kn);
    }
  • 相关阅读:
    Leetcode 3. Longest Substring Without Repeating Characters/ 4. Median of Two Sorted Arrays[二分]
    最大流算法思想和理论的简单理解
    数值线性代数实验-共轭梯度法
    运筹学上机实验
    HDU 1542 Atlantis[扫描线]
    数值实验-高斯消元LU分解
    PAT 1143-Lowest Common Ancestor (30) 二叉树还原
    L2-006. 树的遍历
    hdu-3038 How Many Answers Are Wrong[并查集]
    poj-3253 Fence Repair[霍夫曼树]
  • 原文地址:https://www.cnblogs.com/ztz11/p/9707465.html
Copyright © 2020-2023  润新知