Good Bye 2018 没打记

Posted gloid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Good Bye 2018 没打记相关的知识,希望对你有一定的参考价值。

  场外选手赛时只口胡出了CD感觉非常惨。

  C:f只与gcd(n,k)有关。

  D:考虑每种起始位置,对于跨越的两个排列,只有前一个排列的后缀单减时不产生贡献。答案就非常显然了。注意最后+1,因为这样没考虑n~1的排列。

  E:根据题面给出的定理,n+1号点度数增大时,以该点在已从大到小排序的序列里的位置为分割点,k较大时不等式更难满足,k较小时不等式更易满足,且分割点位置左移。因此每一个位置存在一个连续的合法区间,区间并即为答案,显然其也是一个连续区间。找到任意一个合法答案后二分即可。这个任意答案也可以二分得到,具体地,根据n+1号点度数所在位置及其右边位置是否合法决定二分方向。不等式显然可以树状数组优化一下检验(甚至可以线性?)。

技术分享图片
#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<A||c>Z)&&(c<a||c>z)&&(c<0||c>9)) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<0||c>9) {if (c==-) f=-1;c=getchar();}
    while (c>=0&&c<=9) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,a[N],b[N],tree_size[N],isodd,down,up;
ll tree_sum[N];
void ins(int x){for (int i=x+1;i<=n+1;i+=i&-i) tree_size[i]++,tree_sum[i]+=x;}
int query_size(int k){int s=0;k++;while (k) s+=tree_size[k],k-=k&-k;return s;}
ll query_sum(int k){ll s=0;k++;while (k) s+=tree_sum[k],k-=k&-k;return s;}
int findanyans()
{
    int l=0,r=(n>>1)+1;
    while (l<=r)
    {
        int mid=l+r>>1,k=mid<<1|isodd;
        if (k>n) r=mid-1;
        else
        {
            memset(tree_sum,0,sizeof(tree_sum));
            memset(tree_size,0,sizeof(tree_size));
            for (int i=1;i<=n;i++) b[i]=a[i];b[n+1]=0;
            int pos=0;
            for (int i=1;i<=n+1;i++)
            if (b[i]<k)
            {
                for (int j=n+1;j>i;j--) b[j]=b[j-1];
                b[i]=k;pos=i;break;
            }
            if (pos==0) pos=n+1;
            ll s=0;for (int i=1;i<=n+1;i++) s+=b[i];
            bool flag=1;
            for (int i=n+1;i>=pos;i--)
            {
                if (s>1ll*i*(i-1)+1ll*i*((n+1-i)-query_size(i))+query_sum(i)) {flag=0;break;}
                s-=b[i];ins(b[i]);
            }
            if (!flag) r=mid-1;
            else
            {
                for (int i=pos-1;i>=1;i--)
                {
                    if (s>1ll*i*(i-1)+1ll*i*((n+1-i)-query_size(i))+query_sum(i)) {flag=0;break;}
                    s-=b[i];ins(b[i]);
                }
                if (flag) return mid;else l=mid+1;
            }
        }
    }
    return -1;
}
bool check(int mid)
{
    mid<<=1,mid+=isodd;
    if (mid>n) return 0;
    memset(tree_sum,0,sizeof(tree_sum));
    memset(tree_size,0,sizeof(tree_size));
    for (int i=1;i<=n;i++) b[i]=a[i];b[n+1]=0;
    for (int i=1;i<=n+1;i++)
    if (b[i]<mid)
    {
        for (int j=n+1;j>i;j--) b[j]=b[j-1];
        b[i]=mid;break;
    }
    ll s=0;for (int i=1;i<=n+1;i++) s+=b[i];
    for (int i=n+1;i>=1;i--)
    {
        if (s>1ll*i*(i-1)+1ll*i*((n+1-i)-query_size(i))+query_sum(i)) return 0;
        s-=b[i];ins(b[i]);
    }
    return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("e.in","r",stdin);
    freopen("e.out","w",stdout);
    const char LL[]="%I64d
";
#else
    const char LL[]="%lld
";
#endif
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    sort(a+1,a+n+1);reverse(a+1,a+n+1);
    for (int i=1;i<=n;i++) isodd^=a[i]&1;
    down=up=findanyans();
    if (down==-1) {cout<<-1;return 0;}
    int l=0,r=down;
    while (l<=r)
    {
        int mid=l+r>>1;
        if (check(mid)) down=mid,r=mid-1;
        else l=mid+1;
    }
    l=up,r=(n>>1)+1;
    while (l<=r)
    {
        int mid=l+r>>1;
        if (check(mid)) up=mid,l=mid+1;
        else r=mid-1;
    }
    for (int i=down;i<=up;i++) printf("%d ",i<<1|isodd);
    return 0;
}
View Code

  F:显然每一段都是前一部分步行/游泳,后一部分飞。同样显然的是最后把精力值用完才是最优的,于是总飞行时间也固定了。现在所要做的就是尽量使用游泳来攒精力。那么当处于游泳路段时,只要精力值不会多余就攒精力,否则直接飞到终点。处于步行路段时,只要能满足之后强制飞行路段的需求就飞,否则步行攒精力。怎么这么简单啊?然后才发现原来还有原地徘徊这种操作。感觉上也没有变复杂多少,但实在搞不动了。

 

以上是关于Good Bye 2018 没打记的主要内容,如果未能解决你的问题,请参考以下文章

EOJ Monthly 2018.2 (Good bye 2017)

Good Bye 2018(待更新)

Good Bye 2018

Codeforces 1091 (Good Bye 2018)

Good Bye 2018 A. New Year and the Christmas Ornament

A_B_Good Bye 2018_cf