rt,云斗 50pts,思路就是分段二分,代码挺丑的
本地数据可能造的太随机了,拍不出来
#include <bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
int x = 0,f = 1;char ch = getchar();
while(!isdigit(ch)) (ch == '-') && (f = -1),ch = getchar();
while(isdigit(ch)) x = x*10+ch-48,ch = getchar();
return x*f;
}
const int N = 1e5+10;
LL n,k,x,y,_x[N],_y[N],s1[N],s2[N];
int main()
{
freopen("sj.out","r",stdin);
freopen("wind.out","w",stdout);
int T = read();
while(T--)
{
n = read(),k = read(),x = read(),y = read();
LL m = 1e18;bool f = 0;
for (int i = 0;i < n;i++)
{
_x[i] = read(),_y[i] = read();
s1[i] = (i ? s1[i-1] : 0)+_x[i],s2[i] = (i ? s2[i-1] : 0)+_y[i];
}
if(x == 0 && y == 0){printf("0\n");continue;}
for (LL i = 0;i < n;i++)
{
LL x_1 = x-s1[i],y_1 = y-s2[i];
if(llabs(x_1)+llabs(y_1) <= k*(i+1))
{f = 1,m = min(m,i+1);continue;}
if (k == 0)
{
if (!s1[n-1] || !s2[n-1])
{
if (!s1[n-1] && !x_1 && s2[n-1] && y_1%s2[n-1] == 0 && y_1/s2[n-1] >= 0) f = 1,m = min(m,i+1+y_1/s2[n-1]*n);
if (!s2[n-1] && !y_1 && s1[n-1] && x_1%s1[n-1] == 0 && x_1/s1[n-1] >= 0) f = 1,m = min(m,i+1+x_1/s1[n-1]*n);
continue;
}
if (x_1%s1[n-1] == 0 && y_1%s2[n-1] == 0 && x_1/s1[n-1] == y_1/s2[n-1] && x_1/s1[n-1] >= 0) f = 1,m = min(m,i+1+x_1/s1[n-1]*n);
continue;
}
if (x_1*s1[n-1] > 0)
{
if (y_1*s2[n-1] > 0)
{
LL p1 = llabs(x_1/s1[n-1]),p2 = llabs(y_1/s2[n-1]);bool fl = 0;
if (p1 > p2) swap(p1,p2);
LL l = 1,r = p1;
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
else
{
l = p1+1,r = p2;
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
else
{
l = p2+1,r = r = 1e18/n/max({k,llabs(s1[n-1]),llabs(s2[n-1])});
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
}
}
}
else
{
LL p = llabs(x_1/s1[n-1]);bool fl = 0;
LL l = 1,r = p;
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
else
{
l = p+1,r = 1e18/n/max({k,llabs(s1[n-1]),llabs(s2[n-1])});
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
}
}
}
else
{
if (y_1*s2[n-1] > 0)
{
LL p = llabs(y_1/s2[n-1]);bool fl = 0;
LL l = 1,r = p;
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
else
{
l = p+1,r = 1e18/n/max({k,llabs(s1[n-1]),llabs(s2[n-1])});
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
}
}
else
{
LL l = 1,r = 1e18/n/max({k,llabs(s1[n-1]),llabs(s2[n-1])});bool fl = 0;
if(l == r && (l*n+i+1)*k >= llabs(x_1-s1[n-1]*l)+llabs(y_1-s2[n-1]*l)) fl = 1;
while(l < r)
{
LL mid = (l+r)/2;
if((mid*n+i+1)*k >= llabs(x_1-s1[n-1]*mid)+llabs(y_1-s2[n-1]*mid)) r = mid,fl = 1;
else l = mid+1;
}
if (fl) f = 1,m = min(m,i+1+l*n);
}
}
}
if(f) printf("%lld\n",m);
else printf("-1\n");
}
return 0;
}