Codeforces 1201

C.

对数组排序后后缀加。注意中位数的值不一定等于数组中的某个元素。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long D;
const int maxn=200003;
const D INF=1000000000000ll;
int n;
D k,a[maxn];
int main(){
    scanf("%d%lld",&n,&k);
    for(int i=1;i<=n;i++)scanf("%lld",a+i);
    sort(a+1,a+n+1);
    a[n+1]=INF;
    int i=n/2+1,j=i;
    D cnt=0,ans=a[i];
    while(1){
        for(;j<=n&&a[i]==a[j];j++);
        if(cnt+(j-n/2-1)*(a[j]-a[i])>k)break;
        cnt+=(j-n/2-1)*(a[j]-a[i]);
        ans=a[j];
        i=j;
    }
    ans+=(k-cnt)/(j-n/2-1);
    printf("%lld\n",ans);
    return 0;
}

D.

先预处理出 \(L[i]\)\(R[i]\) 分别表示每行最左边的宝藏和最右边的宝藏。
对于每一行,最优的向上走的安全通道只有4种: \(L[i]\) 左边的和右边的、 \(R[i]\) 左边的和右边的。
\(dp[i][0/1/2/3]\) 表示第 \(i\) 行的4种状态的答案,据此转移即可。
注意特判第一行。细节较多。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long D;
const int maxn=200003;
const D INF=0x3f3f3f3f3f3f3f3f;
int n,m,s,q,L[maxn],R[maxn],b[maxn],x[maxn][4],p[maxn],cnt;
D dp[maxn][4];
int main(){
    scanf("%d%d%d%d",&n,&m,&s,&q);
    fill(L+1,L+n+1,maxn);
    for(int i=1;i<=s;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        L[x]=min(L[x],y);
        R[x]=max(R[x],y);
        p[++cnt]=x;
    }
    sort(p+1,p+cnt+1);
    cnt=unique(p+1,p+cnt+1)-p-1;
    for(int i=1;i<=q;i++)scanf("%d",b+i);
    sort(b+1,b+q+1);
    if(cnt==1){
        int i=p[1];
        printf("%d\n",i==1?
            R[i]-1:
            R[i]-L[i]
            +min(abs(b[1]-L[i]),abs(b[1]-R[i]))
            +i-1+b[1]-1
        );
        return 0;
    }
    for(int _i=1;_i<=cnt;_i++){
        int i=p[_i];
        int *tmp1=lower_bound(b+1,b+q+1,L[i]),*tmp2=lower_bound(b+1,b+q+1,R[i]);
        x[i][0]=tmp1[-1],x[i][1]=*tmp1,x[i][2]=tmp2[-1],x[i][3]=*tmp2;
    }
    for(int j=0;j<=3;j++){
        int i=p[1];
        dp[i][j]=INF;
        if(x[i][j]){
            dp[i][j]=(i==1?
                R[i]-1+abs(x[i][j]-R[i]):
                R[i]-L[i]
                +min(abs(b[1]-L[i])+abs(x[i][j]-R[i]),abs(b[1]-R[i])+abs(x[i][j]-L[i]))
                +i-1+b[1]-1
            );
        }
    }
    for(int _i=2;_i<cnt;_i++){
        for(int j=0;j<=3;j++){
            int i=p[_i],ii=p[_i-1];
            dp[i][j]=INF;
            if(x[i][j]){
                for(int k=0;k<=3;k++){
                    dp[i][j]=min(dp[i][j],dp[ii][k]+R[i]-L[i]
                    +min(abs(x[ii][k]-L[i])+abs(x[i][j]-R[i]),abs(x[ii][k]-R[i])+abs(x[i][j]-L[i]))
                    +i-ii);
                }
            }
        }
    }
//  for(int _i=1;_i<cnt;_i++){
//      for(int j=0;j<=3;j++){
//          int i=p[_i];
//printf("x:%d dp[%d][%d] = %lld\n",x[i][j],i,j,dp[i][j]);
//      }
//  }
    D ans=INF;
    for(int k=0;k<=3;k++){
        int i=p[cnt],ii=p[cnt-1];
        ans=min(ans,dp[ii][k]+R[i]-L[i]
        +min(abs(x[ii][k]-L[i]),abs(x[ii][k]-R[i]))
        +i-ii);
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/BlogOfchc1234567890/p/11440355.html