【学习笔记】[AGC040E] Prefix Suffix Addition
首先对贡献进行一个基本的转化,设 A i = B i + C i A_i=B_i+C_i Ai=Bi+Ci,答案是 ∑ [ B i > B i + 1 ] + ∑ [ C i < C i + 1 ] \sum [B_i>B_{i+1}]+\sum [C_i<C_{i+1}] ∑[Bi>Bi+1]+∑[Ci<Ci+1]。
设 d p i , j dp_{i,j} dpi,j表示 B i = j B_i=j Bi=j时的最小代价,我们从两个角度压缩状态。
 
     
      
       
       
         1.1 
        
       
      
        1.1 
       
      
    1.1  
     
      
       
       
         ∣ 
        
       
         d 
        
        
        
          p 
         
         
         
           i 
          
         
           , 
          
         
           0 
          
         
        
       
         − 
        
       
         d 
        
        
        
          p 
         
         
         
           i 
          
         
           , 
          
          
          
            A 
           
          
            i 
           
          
         
        
       
         ∣ 
        
       
         ≤ 
        
       
         2 
        
       
      
        |dp_{i,0}-dp_{i,A_i}|\le 2 
       
      
    ∣dpi,0−dpi,Ai∣≤2 ,显然,因为这一步最多产生 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2的贡献,也就是说值域是稠密的。
  
     
      
       
       
         1.2 
        
       
      
        1.2 
       
      
    1.2  
     
      
       
       
         d 
        
        
        
          p 
         
         
         
           i 
          
         
           , 
          
         
           j 
          
         
        
       
      
        dp_{i,j} 
       
      
    dpi,j单调递减。
上述性质不难通过打表看出。并且 j j j固定时, k k k越大,转移代价越大,所以我们大力维护这个分段函数即可。
复杂度 O ( n ) O(n) O(n)。注意如果 B B B的后缀是 0 0 0或者 C C C的前缀是 0 0 0时会多算贡献,需要处理一下边界。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[200005];
int x,y,dp;
signed main(){
	cin>>n;for(int i=1;i<=n;i++)cin>>a[i];
	y=a[1];
	for(int i=2;i<=n;i++){
		int l1=max(y,a[i]-a[i-1]+y); // 代价为0 
		int l2=min(y,a[i]-a[i-1]+y); // 代价为1
		int l3=max(x,a[i]-a[i-1]+x),l4=min(y-1,a[i]-a[i-1]+y-1);
		int X=0,Y=0;
		if(l1>a[i]){
			dp++,Y=l2;
			if(l3<=l4)Y=l3;
		}
		else {
			Y=l1,X=l2;
			if(l3<=l4)X=l3;
		}
		x=max(X,0),y=max(Y,0);
	}if(y==0)dp--;
	cout<<dp+1;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号