Skip to content
Logic Formatting

Logic Formatting

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

Posted on 2025 年 1 月 11 日 By jeff

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=\sum\limits_{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<<'\n';  
    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<<'\n';  
    }  
  }  
  return 0;  
}  

標頭、模板請點Submission看
Submission

ojcode codeforceojcode思維

文章導覽

Previous post
Next post

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

近期文章

  • B. Kyoya and Permutation 解析(思維、數論、DP)
  • G. Guess One Character 解析(思維)
  • E. The Road to Berland is Paved With Good Intentions 解析(思維、2-SAT、SCC、拓樸排序)
  • E. Xor-sequences 解析(思維、矩陣快速冪)
  • LeetCode. First Missing Positive 解析(思維)

近期留言

尚無留言可供顯示。

彙整

  • 2025 年 2 月
  • 2025 年 1 月

分類

  • ojcode
©2026 Logic Formatting | WordPress Theme by SuperbThemes