답안 #712275

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
712275 2023-03-18T13:50:58 Z bin9638 Shortcut (IOI16_shortcut) C++17
0 / 100
494 ms 127588 KB
#include <bits/stdc++.h>

#ifndef SKY
#include "shortcut.h"
#endif // SKY

using namespace std;

#define ll long long
#define pb push_back
#define N 4010
#define ii pair<ll,int>
#define fs first
#define sc second

int n;
ll sum[N],C,d[N],left_pair[N],right_pair[N],l[N],r[N],f[N][N],dp[N][N];

struct rmq
{
    ll rmq[N][21]={};
    int LOG;

    void init(ll val)
    {
        memset(rmq,-0x3f3f,sizeof(rmq));
        LOG=log2(n);
        for(int i=1;i<=n;i++)
            rmq[i][0]=sum[i]*val+d[i];
        for(int k=1;k<=LOG;k++)
            for(int i=1;i<=n;i++)
                if(i+(1<<(k-1))<=n)
                    rmq[i][k]=max(rmq[i][k-1],rmq[i+(1<<(k-1))][k-1]);
    }

    ll get_max(int l,int r)
    {
        int k=31-__builtin_clz(r-l+1);
        return max(rmq[l][k],rmq[r-(1<<k)+1][k]);
    }
}tru,cong;

bool check(ll x)
{
    memset(dp,-0x3f3f,sizeof(dp));
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(sum[j]-sum[i]+d[i]+d[j]>x)
            {
              //  cout<<i<<" "<<j<<endl;
                dp[i][j]=d[i]+sum[i]+d[j]-sum[j];
            }
    for(int i=n;i>=1;i--)
        for(int j=i;j<=n;j++)
        {
            if(i<j)
                dp[i][j]=max(dp[i][j],dp[i+1][j]);
            if(i<j)
                dp[i][j]=max(dp[i][j],dp[i][j-1]);
            if(dp[i][j]-sum[i]+sum[j]<=x&&f[i][j]<=x)
            {
               // cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
                return 1;
            }
        }
    return 0;
}

ll find_shortcut(int cc, vector<int> vc, vector<int> DD, int vl)
{
    n=cc;
    C=vl;
    for(int i=2;i<=n;i++)
        sum[i]=1ll*vc[i-2]+sum[i-1];
    for(int i=1;i<=n;i++)
        d[i]=DD[i-1];
    memset(l,-0x3f3f,sizeof(l));
    memset(r,-0x3f3f,sizeof(r));
    for(int i=1;i<=n;i++)
    {
        l[i]=d[i]-sum[i];
        if(i>1)
            l[i]=max(l[i],l[i-1]);
        left_pair[i]=left_pair[i-1];
        for(int j=1;j<i;j++)
            left_pair[i]=max(left_pair[i],sum[i]-sum[j]+d[i]+d[j]);
       // cout<<l[i]<<" "<<left_pair[i]<<endl;
    }
    for(int i=n;i>=1;i--)
    {
        r[i]=d[i]+sum[i];
        if(i<n)
            r[i]=max(r[i],r[i+1]);
        right_pair[i]=right_pair[i+1];
        for(int j=n;j>i;j--)
            right_pair[i]=max(right_pair[i],sum[j]-sum[i]+d[i]+d[j]);
    }
    tru.init(-1);
    cong.init(1);
    for(int i=1;i<=n;i++)
    {
        int pos=i;
        for(int j=i;j<=n;j++)
        {
            f[i][j]=max(left_pair[i],max(right_pair[j],l[i]+r[j]+sum[i]-sum[j]+min(C,sum[j]-sum[i])));
            while(pos<j&&sum[pos+1]-sum[i]<=sum[j-1]-sum[pos+1]+min(C,sum[j]-sum[i]))
                pos++;
            f[i][j]=max(f[i][j],l[i-1]+cong.get_max(i,pos));
            if(pos<j)
            {
                f[i][j]=max(f[i][j],l[i-1]+sum[j-1]+tru.get_max(pos+1,j)+min(C,sum[j]-sum[i]));
            }
        }
    }
   // cout<<tru.get_max(3,3)<<endl;
    for(int i=n;i>=1;i--)
    {
        int pos=i;
        for(int j=i;j>=1;j--)
        {
            while(pos>j&&sum[i]-sum[pos-1]<=sum[pos-1]-sum[j]+min(C,sum[i]-sum[j]))
                pos--;
            f[j][i]=max(f[j][i],r[i+1]+tru.get_max(pos,i));
          //  if(j==2&&i==4)
            //    cout<<pos<<" "<<r[i]<<" "<<tru.get_max(pos,i)<<endl;
            if(pos>j)
            {
                f[j][i]=max(f[j][i],r[i+1]+cong.get_max(j,pos-1)-sum[j]+min(C,sum[i]-sum[j]));
            }
        }
    }
    //cout<<f[2][4]<<endl;
   // cout<<f[1][3]<<endl;
   // cout<<check(80)<<endl;
    //cout<<f[1][2]<<endl;
   // return 0;
    ll u=1,v=1ll*n*(ll)1e9,res=0;
    while(u<=v)
    {
        ll mid=(u+v)/2;
        if(check(mid))
        {
            res=mid;
            v=mid-1;
        }else
            u=mid+1;
    }
    return res;
}

#ifdef SKY
int main()
{
    freopen("A.inp","r",stdin);
    freopen("A.out","w",stdout);
    int n,c;
    vector<int>l,d;
    cin>>n;
    for(int i=0;i<n-1;i++)
    {
        int u;
        cin>>u;
        l.pb(u);
    }
    for(int i=0;i<n;i++)
    {
        int u;
        cin>>u;
        d.pb(u);
    }
    cin>>c;
    cout<<find_shortcut(n,l,d,c);
}
#endif
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 471 ms 127568 KB n = 4, 80 is a correct answer
2 Incorrect 494 ms 127588 KB n = 9, incorrect answer: jury 110 vs contestant 100
3 Halted 0 ms 0 KB -