Luo Gu P1081-- travel by car

Portal: QAQQAQ

 

题意 Notes:

1 is a front to back away, not looking back

2. Small A small B turns to open, start with a small A is open, and a small A is the (time debugging check this for a long time) near the second point

3. If the absolute value of the difference between the same low altitude closer, and the first asking if the same ratio is more preferably high altitude

 

Idea: Let a number from the pre-treatment and sub-point i recently near point, there is no or -1 (list up to O (n), but with STL O (nlog (n)) is more than enough, but also a small amount of code)

And then multiplying the pre-walking wheel 2 ^ j A distance away from the point number i, B's journey, and finally completed the wheels stop point (defined once for each taking an AB)

Note It may take half round, and last about A B not go away.

 

Write the title process:

Gangster MYY told me not to hurry, violence hit 70 points, then hit two hours of violence (STL really so hard to check ah QAQ) played after violent told me to delete all the main program rewrite. . . . .

See next direct violence HCY did not play a direct positive solution AC, the mentality of collapse. . .

Then able to get out in the absence of special circumstances and sentenced AB write positive half order, generally written anti raised for a long time, but in the end it was quite rewarding to do ( feel weak ah .. )

 

Code:

#include<bits/stdc++.h>
#define m_k make_pair
#define ll long long
using namespace std;
const ll N=102000;
const ll inf=(ll)5e18;

ll f[N][2],n,m,a[N],x0;
//0:closest 1:second closest
ll dp[N][20][2],Bits[20],p[N][20];
//0:disB 1:disA p:finalpos AB为一轮,走2^t轮 

ll _abs(ll x)
{
    if(x<0) return -x;
    else return x;
}

set<pair<ll,ll> > st;
vector<pair<ll,ll> > tmp;
void init()
{
    memset(f,-1,sizeof(f));
    st.insert(m_k(a[n],n));
    st.insert(m_k(a[n-1],n-1));
    f[n-1][0]=n;
    for(ll i=n-2;i>=1;i--)
    {
        ll bl=0;
        tmp.clear();
        set<pair<ll,ll> > :: iterator it;
        it=st.lower_bound(m_k(a[i],i));
        if(it!=st.end()) tmp.push_back(*it),it++,bl++;
        if(it!=st.end()) tmp.push_back(*it);
        if(bl) it--;
        it--;
        set<pair<ll,ll> > :: iterator be;
        be=st.begin(); be--;
        if(it!=be) tmp.push_back(*it),it--;
        if(it!=be) tmp.push_back(*it);
        ll ans1=inf,ans2=inf;
        for(ll j=0;j<(ll)tmp.size();j++)
        {
            if(ans1>_abs(a[i]-tmp[j].first)||(ans1==_abs(a[i]-tmp[j].first)&&a[f[i][0]]>tmp[j].first))
            {
                f[i][1]=f[i][0]; ans2=ans1;
                f[i][0]=tmp[j].second; ans1=_abs(a[i]-tmp[j].first);
            }
            else if(ans2>_abs(a[i]-tmp[j].first)||(ans2==_abs(a[i]-tmp[j].first)&&a[f[i][1]]>tmp[j].first))
            {
                f[i][1]=tmp[j].second; ans2=_abs(a[i]-tmp[j].first);
            }
        }
        st.insert(m_k(a[i],i));
    }
}

void ready()
{
    memset(p,-1,sizeof(p));
    memset(dp,-1,sizeof(dp));
    for(ll i=1;i<=n;i++)
    {
        ll pos=f[i][1]; if(pos==-1) continue;
        dp[i][0][1]=_abs(a[pos]-a[i]);
        if(f[pos][0]==-1) continue; 
        dp[i][0][0]=_abs(a[pos]-a[f[pos][0]]);
        p[i][0]=f[pos][0];
    }
    for(ll j=1;j<20;j++)
    {
        for(ll i=1;i<=n;i++)
        {
            for(ll k=0;k<=1;k++)
                if(dp[i][j-1][k]!=-1&&dp[p[i][j-1]][j-1][k]!=-1) dp[i][j][k]=dp[i][j-1][k]+dp[p[i][j-1]][j-1][k];
            if(p[i][j-1]!=-1) p[i][j]=p[p[i][j-1]][j-1];
            
        }
    }
}

ll suma,sumb;
double calc(ll x,ll y)
{
    if(y==0) return inf*1.0;
    return(x*1.0)/(y*1.0);
}

int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
    init();
    ready();
    scanf("%lld",&x0);
    double ans=inf*1.0;
    ll now=0;
    a[0]=-inf;
    for(int i=1;i<=n;i++)
    {
        ll suma=0,sumb=0,pos=i;
        for(int j=19;j>=0;j--)
        {
            if(dp[pos][j][0]==-1||dp[pos][j][1]==-1||p[pos][j]==-1) continue;
            if(dp[pos][j][0]+dp[pos][j][1]+suma+sumb>x0) continue;
            suma+=dp[pos][j][1];
            sumb+=dp[pos][j][0];
            pos=p[pos][j];
        }
        if(dp[pos][0][1]+suma+sumb<=x0&&dp[pos][0][1]!=-1) suma+=dp[pos][0][1];
        if(ans>calc(suma,sumb)||(ans==calc(suma,sumb)&&a[i]>a[now]))
        {
            now=i;
            ans=calc(suma,sumb);
        }
    }
    cout<<now<<endl; ll pos;
    scanf("%lld",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld",&pos,&x0);
        suma=0; sumb=0;
        for(int j=19;j>=0;j--)
        {
            if(dp[pos][j][0]==-1||dp[pos][j][1]==-1||p[pos][j]==-1) continue;
            if(dp[pos][j][0]+dp[pos][j][1]+suma+sumb>x0) continue;
            suma+=dp[pos][j][1];
            sumb+=dp[pos][j][0];
            pos=p[pos][j];
        }
        if(dp[pos][0][1]+suma+sumb<=x0&&dp[pos][0][1]!=-1) suma+=dp[pos][0][1];
        printf("%lld %lld\n",suma,sumb);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Forever-666/p/11210604.html