[海军国际项目办公室]铺设道路
铺设道路
题目

 
题解
首先,我们有一个对于区间加减的很经典的转化,通过差分的转化使得我们的区间加减变成单点的改变。
 我们定义 
     
      
       
        
        
          b 
         
        
          i 
         
        
       
         = 
        
        
        
          d 
         
        
          i 
         
        
       
         − 
        
        
        
          d 
         
         
         
           i 
          
         
           − 
          
         
           1 
          
         
        
       
      
        b_i=d_{i}-d_{i-1} 
       
      
    bi=di−di−1,那么我们对区间 
     
      
       
       
         ( 
        
       
         l 
        
       
         , 
        
       
         r 
        
       
         ) 
        
       
      
        (l,r) 
       
      
    (l,r)进行操作相当于让 
     
      
       
        
        
          b 
         
        
          l 
         
        
       
         − 
        
       
         1 
        
       
      
        b_{l}-1 
       
      
    bl−1, 
     
      
       
        
        
          b 
         
         
         
           r 
          
         
           + 
          
         
           1 
          
         
        
       
         + 
        
       
         1 
        
       
      
        b_{r+1}+1 
       
      
    br+1+1,其代价为 
     
      
       
       
         ( 
        
       
         r 
        
       
         − 
        
       
         l 
        
       
         + 
        
       
         1 
        
        
        
          ) 
         
        
          2 
         
        
       
      
        (r-l+1)^2 
       
      
    (r−l+1)2。
 显然, 
     
      
       
        
        
          d 
         
        
          i 
         
        
       
         = 
        
        
        
          ∑ 
         
         
         
           j 
          
         
           = 
          
         
           1 
          
         
        
          i 
         
        
        
        
          b 
         
        
          j 
         
        
       
      
        d_{i}=\sum_{j=1}^{i}b_{j} 
       
      
    di=∑j=1ibj,也就是说在合法情况下,我们的 
     
      
       
       
         d 
        
       
      
        d 
       
      
    d的前缀和应该是始终不小于 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0的。
 由于要让总的操作次数最小,我们肯定只会让 
     
      
       
       
         b 
        
       
         > 
        
       
         0 
        
       
      
        b>0 
       
      
    b>0的 
     
      
       
        
        
          b 
         
        
          l 
         
        
       
         − 
        
       
         1 
        
       
      
        b_{l}-1 
       
      
    bl−1,让 
     
      
       
        
        
          b 
         
         
         
           r 
          
         
           + 
          
         
           1 
          
         
        
       
         < 
        
       
         0 
        
       
      
        b_{r+1}<0 
       
      
    br+1<0的 
     
      
       
        
        
          b 
         
         
         
           r 
          
         
           + 
          
         
           1 
          
         
        
       
         + 
        
       
         1 
        
       
      
        b_{r+1}+1 
       
      
    br+1+1。
 显然,既然它的前缀和是始终大于 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0的,所以我们是一定找得到这样的匹配的 
     
      
       
       
         ( 
        
       
         l 
        
       
         , 
        
       
         r 
        
       
         ) 
        
       
      
        (l,r) 
       
      
    (l,r)。
 而我们最后的到的序列有是一个全 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0的序列,而我们有只会让 
     
      
       
       
         d 
        
       
      
        d 
       
      
    d减小,所以我们在过程中一定是保证 
     
      
       
       
         d 
        
       
      
        d 
       
      
    d全部大于 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0,即所有操作都是合法的。
最小操作次数显然是 
     
      
       
       
         ∑ 
        
       
         max 
        
       
          
        
       
         ( 
        
        
        
          b 
         
        
          i 
         
        
       
         , 
        
       
         0 
        
       
         ) 
        
       
      
        \sum \max(b_{i},0) 
       
      
    ∑max(bi,0)。
 我们关键是要怎么匹配 
     
      
       
       
         b 
        
       
      
        b 
       
      
    b使得我们最后的代价和最大于最小。
 由于我们的代价是平方项,而它们一次方状况下的总和是固定的,所以我们肯定要让它们长的段越多权值肯定越大,较长的段越小权值肯定越小。
 所以我们肯定是对于 
     
      
       
        
        
          b 
         
        
          i 
         
        
       
         < 
        
       
         0 
        
       
      
        b_{i}<0 
       
      
    bi<0的 
     
      
       
        
        
          b 
         
        
          i 
         
        
       
      
        b_{i} 
       
      
    bi匹配离他最近的 
     
      
       
        
        
          b 
         
        
          j 
         
        
       
         > 
        
       
         0 
        
       
      
        b_{j}>0 
       
      
    bj>0的 
     
      
       
        
        
          b 
         
        
          j 
         
        
       
      
        b_{j} 
       
      
    bj,将更远的留给后面使得我们的总贡献越大。
 而将其匹配最远的 
     
      
       
        
        
          b 
         
        
          j 
         
        
       
         < 
        
       
         0 
        
       
      
        b_{j}<0 
       
      
    bj<0的 
     
      
       
        
        
          b 
         
        
          j 
         
        
       
      
        b_{j} 
       
      
    bj可以使得所有的长度都较短,使得总贡献较小。
 该匹配过程显然可以通过队列进行维护。
时间复杂度 O ( n ) O\left(n\right) O(n)。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 300005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x<<'\n'
typedef long long LL;
typedef unsigned long long uLL;     
const LL INF=0x3f3f3f3f3f3f3f3f;  
const int mo=1e9+7;
const int inv2=499122177;
const int jzm=2333;
const int n1=50;
const int zero=10000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-5;
typedef pair<LL,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
char gc(){static char buf[10000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,10000000,stdin),p1==p2)?EOF:*p1++;}
//#define getchar gc
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x>9)print(x/10);putchar(x%10+'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
int n,d[MAXN],b[MAXN],ansmax,ansmin;LL ans;
deque<pii>q;
signed main(){
	freopen("road.in","r",stdin);
	freopen("road.out","w",stdout);
	read(n);for(int i=1;i<=n;i++)read(d[i]);
	for(int i=1;i<=n+1;i++)b[i]=d[i]-d[i-1],ans+=1ll*max(b[i],0);
	for(int i=1;i<=n+1;i++){
		if(b[i]>0)q.push_back(mkpr(i,b[i]));
		else while(b[i]<0){
			pii t=q.front();q.pop_front();
			int tmp=min(-b[i],t.sec);b[i]+=tmp;t.sec-=tmp;
			Add(ansmin,1ll*(i-t.fir)*(i-t.fir)%mo*tmp%mo,mo);
			if(t.sec)q.push_front(t);
		}
	}
	while(!q.empty())q.pop_back();
	for(int i=1;i<=n+1;i++)b[i]=d[i]-d[i-1];
	for(int i=1;i<=n+1;i++){
		if(b[i]>0)q.push_back(mkpr(i,b[i]));
		else while(b[i]<0){
			pii t=q.back();q.pop_back();
			int tmp=min(-b[i],t.sec);b[i]+=tmp;t.sec-=tmp;
			Add(ansmax,1ll*(i-t.fir)*(i-t.fir)%mo*tmp%mo,mo);
			if(t.sec)q.push_back(t);
		}
	}
	printf("%lld\n%d\n%d\n",ans,ansmax,ansmin);
	return 0;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号