数据过水
查看原帖
数据过水
879743
Baseplate27楼主2024/3/7 21:33

没有判斜率之间的大小关系就可以通过所有数据:

#include <bits/stdc++.h>

using namespace std;
#define int long long
#define ll __int128
const int maxn=1e6+10;
int n,k,X,Y;
int a[maxn],b[maxn];
ll sum1,sum2;
inline ll abs(ll a)
{
    if(a>0) return a;
    else return -a;
}
inline ll min(ll a,ll b)
{
    if(a<b) return a;
    return b;
}
inline ll calc(ll x,ll y,ll nowx,ll nowy)
{
    ll t1=0,t2=0;
    if(x>0&&nowx<0) t1=x+(-nowx);
    else if(x<0&&nowx>0) t1=-x+nowx;
    else t1=abs(nowx-x);
    if(y>0&&nowy<0) t2=y+(-nowy);
    else if(y<0&&nowy>0) t2=-y+nowy;
    else t2=abs(nowy-y);
    return t1+t2;
}
inline bool chk(ll x,ll i,ll t1,ll t2)
{
    ll now1=x*sum1+t1,now2=x*sum2+t2;
    return calc(X,Y,now1,now2)<=k*(x*n+i+1);
}
int tpos[maxn],c;
ll sollr(int L,int R)
{
    ll now1=(L-1)*sum1,now2=(L-1)*sum2,st=calc(X,Y,0,0);
    for(signed i=0;i<n;i++)
    {
        now1+=a[i],now2+=b[i];
        ll dis=calc(X,Y,now1,now2);
        if(dis<=k*(i+1+(L-1)*n))
        {
            return i+1+(L-1)*n;
        }
    }
    int t1=0,t2=0;
    int l=0,r=2e18,ans=-1;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(L+mid-1>R)
        {
            r=mid-1;
            continue;
        }
        if(chk(mid+L-1,-1,0,0)) r=mid-1,ans=mid;
        else l=mid+1;
    }
    ll minn=2e18;
    if(ans!=-1)
    {
        minn=min(minn,ans*n+(L-1)*n);
    }
    for(register signed i=0;i<n;i++)
    {
        
        t1+=a[i],t2+=b[i];
        c=0;
        if((X-t1-(L-1)*sum1)*sum1>0)
        {
            tpos[++c]=(X-t1-(L-1)*sum1)/sum1+1;
        }
        if((Y-t2-(L-1)*sum2)*sum2>0) tpos[++c]=(Y-t2-(L-1)*sum2)/sum2+1;
        tpos[++c]=0,tpos[++c]=2e18;
        sort(tpos+1,tpos+1+c);
        for(register signed j=1;j<c;j++)
        {
            int l=tpos[j],r=tpos[j+1]-1,ans=-1;
            //cout<<i<<" "<<(int)l<<" "<<(int)r<<" "<<(int)L<<endl;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(L+mid-1>R)
                {
                    r=mid-1;
                    continue;
                }
                if(chk(mid+L-1,i,t1,t2)) r=mid-1,ans=mid;
                else l=mid+1;
            }
            if(ans!=-1)
            {
                minn=min(minn,ans*n+i+1+(L-1)*n);
            }
        }
        
    }
    if(minn>1e18) return -1;
    return minn;
}
int pos[20],tot;
void sol()
{
    if(X==0&&Y==0)
    {
        puts("0");
        return ;
    }
    pos[++tot]=1,pos[++tot]=1e18;
    if(sum1*X>0)
    {
        pos[++tot]=X/sum1;
    }
    if(sum2*Y>0)
    {
        pos[++tot]=Y/sum2;
    }
    sort(pos+1,pos+1+tot);
    for(int i=1;i<tot;i++)
    {
        int ans=sollr(pos[i],pos[i+1]-1);
        if(ans!=-1)
        {
            printf("%lld\n",ans);
            return ;
        }
    }
    puts("-1");
}
signed main()
{
    int T;
    scanf("%lld",&T);
    while(T--)
    {
        sum1=sum2=tot=0;
        scanf("%lld%lld%lld%lld",&n,&k,&X,&Y);
        for(signed i=0;i<n;i++) scanf("%lld%lld",&a[i],&b[i]),sum1+=a[i],sum2+=b[i];
        int t1=0,t2=0;
        bool flag=0;
        if(!X&&!Y)
        {
            puts("0");
            continue;
        }
        for(int i=0;i<100;i++)
        {
            t1+=a[i%n],t2+=b[i%n];
            if(calc(X,Y,t1,t2)<=(i+1)*k)
            {
                flag=1;
                printf("%lld\n",i+1);
                break;
            }
        }
        if(flag)
        {
            continue;
        }
        sol();
    }
    return 0;
}
2024/3/7 21:33
加载中...