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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    sfs2x 连接 mongodb
    java websocket
    webstorm 4.0 注册码
    解决 sfs2 admin tool 找不到扩展
    window 注册表五大类
    opengl 学习第二日
    java google Protobuf
    扩展 java sencha touch PhonegapPlugin
    sencha touch2 kryonet socket phonegap 通信 作者:围城
    sencha touch2 layout 笔记
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13576115.html
Copyright © 2011-2022 走看看