zoukankan      html  css  js  c++  java
  • CF819B Mister B and PR Shifts(思维)

    做这题细节比较多,要想清楚实际的含义

    首先我们肯定是想着枚举看看把哪些提到最前面

    对于这题我们发现我们要维护的有两种情况,一种是相减小于0,一种是相减大于0

    因此我们分两种情况讨论,并且注意状态的变化,具体细节看代码注释

     #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> pll;
    const int N=2e6+10;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    ll a[N],sign[N];//sign表示移动i次变成第二类点的个数
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        ll pcnt=0,pres=0;
        ll ncnt=0,nres=0;
        for(ll i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]<=i){
                ncnt++;
                nres+=(i-a[i]);
            }
            else{
                sign[a[i]-i]++;
                pcnt++;
                pres+=(a[i]-i);
            }
        }
        ll ans=pres+nres;
        ll k=0;
        for(i=1;i<n;i++){
            pres-=pcnt;//第一类答案都减
            pcnt-=sign[i];//失去变成第二类的
            nres+=ncnt;//第二类答案都是加
            ncnt+=sign[i];//多出来的第二类
            ll x=a[n-i+1];//最后一位移到队首
            ncnt--;
            nres-=(n+1-x);//因为先行计算,导致最后一位到了n+1处,我们先减去他的贡献后把他移到第一位
            if(x>1){
                pcnt++;
                pres+=(a[n-i+1]-1);
                sign[x-1+i]++;//如果他又变成了第二类点,那么要加上他之前移动的i步再计算
            }
            else{
                ncnt++;
            }
            if(ans>pres+nres){
                ans=pres+nres;
                k=i;
            }
        }
        cout<<ans<<" "<<k<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    laravel、TP、YII框架的优缺点
    关于如何关闭Laravel中严格模式的两种方法
    Laravel扩展阿里云OSS对象存储
    Laravel权限管理的应用记录
    laravel原生MySQL之Group记录
    laravel导出Xlsx
    软件工程课的认识
    斗兽棋项目开发计划书
    斗兽棋测试计划说明书
    测试报告分析
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13576115.html
Copyright © 2011-2022 走看看