• C2. Pokémon Army (hard version) 解析(思維)


    Codeforce 1420 C2. Pokémon Army (hard version) 解析(思維)

    今天我們來看看CF1420C2
    題目連結

    題目
    略,請直接看原題。

    前言

    根本想不到這個等價的想法

    想法

    首先注意到,如果數列其中一段是遞增數列,那麼我們最好的方式就是減去最小的那個數字並且加上最大的那個數字。因為這樣做得到的值是(max-min),而如果我們選取這遞增數列中間的兩個數字,就會使得值減小。
    因此,我們發現,答案就是所有local maximum-local minimum。(local maximum代表某個(a[i])使得(a[i]>a[i-1])(a[i]>a[i+1]),反之亦然。當然,第一個選和最後一個選的數字要是maximum)
    而接下來我們會發現,如果我們只以local maximum-local minimum來計算值,實在不容易計算數字調換後的答案,因此我們需要一個新穎的想法。
    (ans=sumlimits_{i=1}^{n}max{0,a[i]-a[i-1]})(思考一下,這樣計算和我們上面說的方法是一樣的)
    如此一來,每次調換(a[l],a[r]),只需要先把(a[l],a[r])造成的影響減掉,並且把新的影響加上去即可。

    注意:(l+1=r)時特別考慮,且我們要初始化(a[0]=a[n+1]=0)

    程式碼:

    const int _n=3e5+10;
    int t,n,q,l,r,a[_n];
    ll ans;
    main(void) {cin.tie(0);ios_base::sync_with_stdio(0);
      cin>>t;while(t--){
        ans=0;
        cin>>n>>q;rep(i,1,n+1)cin>>a[i]; a[0]=a[n+1]=0;
        rep(i,1,n+1)ans+=max(0,a[i]-a[i-1]); cout<<ans<<'
    ';
        while(q--){
          cin>>l>>r;
          ans-=max(0,a[l]-a[l-1])+max(0,a[l+1]-a[l]),ans-=max(0,a[r]-a[r-1])+max(0,a[r+1]-a[r]);
          if(l+1==r)ans+=max(0,a[l+1]-a[l]);
          swap(a[l],a[r]);
          ans+=max(0,a[l]-a[l-1])+max(0,a[l+1]-a[l]),ans+=max(0,a[r]-a[r-1])+max(0,a[r+1]-a[r]);
          if(l+1==r)ans-=max(0,a[l+1]-a[l]);
          cout<<ans<<'
    ';
        }
      }
      return 0;
    }
    

    標頭、模板請點Submission看
    Submission

  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    大二上学期软件工程概论学习进度表(第十二周)
    构建之法阅读笔记03
    四则运算二
    GCD
    Category的使用
    适配6 、6P 来源互联网
    UIView阴影和圆角的关系
    NSSet类型 以及与NSArray区别
  • 原文地址:https://www.cnblogs.com/petjelinux/p/13730503.html
Copyright © 2020-2023  润新知