• Mister B and PR Shifts,题解


    题目链接

    分析:

      题意很明白,不再多说了,直接分析题目,首先想一想暴力,直接枚举起点,然后求出来,时间复杂度n*n,显然不太好,所以我们考虑换一种方法枚举,当然本质还是枚举,其实你会发现变化i次和i+1次是由很强的关联性的,除了末尾的元素之外,i+1每个元素提供的值都会和i的相差1,而末尾元素之接特判一下就好了,我们只需要知道的是没次有多少个将会-1的(自然+1的也可以之接求得),我们来想一下这个问题,如果不考虑后面的元素回到前面,那么其实每个元素在什么时候由加变减是确定的,可以直接找到,而对于从后面新加入的元素,开始当然可以加上,然后记录一下从哪里开始把它减掉就好了,当然如果是1的话加上就会立刻减掉,也没有问题,最后再处理答案就好了。

      当然,数组开2e6防止溢出。

    代码:

    #include <cstdio>
    const int maxn=2e6+10;
    int a[maxn];
    int cj[maxn];
    int kj[maxn];
    long long ans[maxn];
    long long Abs(int a){
        long long s=(long long)a;
        return s>0?s:-s;
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(a[i]-i>=0)
                cj[a[i]-i]++;
        }
        int s=0;
        long long mi=1e18;
        for(int i=1;i<=n;i++){
            ans[0]+=Abs(a[i]-i);
            kj[0]+=cj[i-1];
        }
        for(int i=1;i<=n-1;i++){
            kj[i]+=kj[i-1]-cj[i-1];
            cj[a[n-i+1]-1+i]++;
            kj[i+1]++;
        }
        for(int i=1;i<=n-1;i++){
            ans[i]=ans[i-1]-Abs(a[n-i+1]-n)+Abs(a[n-i+1]-1);
            ans[i]-=(long long)kj[i];
            ans[i]+=(long long)n-(long long)1-(long long)kj[i];
        }
        for(int i=0;i<=n-1;i++)
            if(ans[i]<mi){
                mi=ans[i];
                s=i;
            }
        printf("%lld %d",mi,s);
    }
  • 相关阅读:
    工厂模式
    不错公众号
    linux 下的 正则表达式(awk,sed,awk)学习
    CentOS 7 中安装 bcc-tools
    docker
    Python爬去知乎上问题下所有图片
    过滤重复数据取一条
    阿里云80端口被系统占用
    过滤重复项取时间最近的数据
    Layui的几个问题记录一下
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12852494.html
Copyright © 2020-2023  润新知