用的是分类讨论的方法,判断从什么时候开始 x/y 风向变为做 正/负 贡献
6,7,9,10 号点在不该输出 -1 的地方输出了 -1
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int __int128
#define lyx return
#define AKIOI 0
const int one=1;
const int INF=(one<<126);
inline int read(){
int ret=0;
char ch=' ',c=getchar();
while(!('0'<=c&&c<='9')) ch=c,c=getchar();
while('0'<=c&&c<='9') ret=(ret<<1)+(ret<<3)+(c^48),c=getchar();
return ch=='-'?-ret:ret;
}
inline int absll(int x){ return x<0?-x:x; }
void read(int &x){
// read a __int128 variable
char c; bool f = 0;
while(((c = getchar()) < '0' || c > '9') && c != '-');
if(c == '-'){f = 1; c = getchar();}
x = c - '0';
while((c = getchar()) >= '0' && c <= '9')x = x * 10 + c - '0';
if(f) x = -x;
}
void write(int x){
// print a __int128 variable
if(x < 0){putchar('-'); x = -x;}
if(x > 9)write(x / 10);
putchar(x % 10 + '0');
}
int min(int x,int y){ return x<y?x:y; }
int max(int x,int y){ return x>y?x:y; }
int T;
int n,k,x,y;
const int N=1e5+10;
int xx[N],yy[N];
int dx[N],dy[N];
signed main(){
// freopen("6.in","r",stdin);
// freopen("wind.out","w",stdout);
read(T);
while(T--){
read(n),read(k),read(x),read(y);
if(x==0&&y==0){
for(int i=1;i<=n;i++) read(x),read(y);
printf("0\n");
continue;
}
int wk=0,mi=INF,ans;
bool flag=false;
for(int i=1;i<=n;i++){
read(xx[i]),read(yy[i]);
dx[i]=dx[i-1]+xx[i];
dy[i]=dy[i-1]+yy[i];
wk+=k;
int cost=absll(dx[i]-x)+absll(dy[i]-y);
if(cost<=wk&&flag==false){
flag=true;
write(i);
putchar('\n');
}
}
int ki=k;
k*=n;
const int dxn=dx[n],dyn=dy[n];
if(flag) continue;
int xt,yt,mi1,mi2;
for(int i=1;i<=n;i++){
if((dx[i]<=x&&dxn<=0)||(dx[i]>=x&&dxn>=0)) xt=-1;
else xt=absll(x-dx[i])/absll(dxn);
if((dy[i]<=y&&dyn<=0)||(dy[i]>=y&&dyn>=0)) yt=-1;
else yt=absll(y-dy[i])/absll(dyn);
mi1=min(xt,yt);
mi2=max(xt,yt);
int cost=absll(dx[i]-x)+absll(dy[i]-y)-ki*i;
// printf("xt=%lld yt=%lld cost=%lld\n",xt,yt,cost);
int work1=absll(dxn)+absll(dyn)+k;
if(work1<=0) continue;
int tim=(cost-1)/work1+1;
// printf("work1=%lld tim=%lld\n",work1,tim);
if(tim<=mi1){
if(tim<mi) mi=tim,ans=i;
else if(tim==mi&&i<ans) ans=i;
continue;
}
if(mi1!=-1){
cost-=mi1*work1;
dx[i]+=mi1*dxn,dy[i]+=mi1*dyn;
if(mi1==xt) cost+=absll(dx[i]+dxn-x)-absll(dx[i]-x);
else cost-=absll(dxn);
if(mi1==yt) cost+=absll(dy[i]+dyn-y)-absll(dy[i]-y);
else cost-=absll(dyn);
tim=mi1+1;
dx[i]+=dxn,dx[i]+=dyn;
if(cost<=k){
if(tim<mi) mi=tim,ans=i;
else if(tim==mi&&i<ans) ans=i;
continue;
}
cost-=k;
}
else tim=0;
int work2=(tim>xt?-1:1)*absll(dxn)+(tim>yt?-1:1)*absll(dyn)+k;
if(work2<=0) continue;
tim+=(cost-1)/work2+1;
// printf("work2=%lld tim=%lld\n",work2,tim);
if(tim<=mi2){
if(tim<mi) mi=tim,ans=i;
else if(tim==mi&&i<ans) ans=i;
continue;
}
if(mi2!=-1){
if(mi1==-1) mi1=0;
cost-=(mi2-mi1)*work2;
dx[i]+=(mi2-mi1)*dxn,dy[i]+=(mi2-mi1)*dyn;
if(mi2==xt) cost+=absll(dx[i]+dxn-x)-absll(dx[i]-x);
else cost+=absll(dxn);
if(mi2==yt) cost+=absll(dy[i]+dyn-y)-absll(dy[i]-y);
else cost+=absll(dyn);
tim=mi2+1;
dx[i]+=dxn,dy[i]+=dyn;
if(cost<=k){
if(tim<mi) mi=tim,ans=i;
else if(tim==mi&&i<ans) ans=i;
continue;
}
cost-=k;
}
else tim=0;
int work3=k-absll(dxn)-absll(dyn);
if(work3<=0) continue;
tim+=(cost-1)/work3+1;
if(tim<mi) mi=tim,ans=i;
else if(tim==mi&&i<ans) ans=i;
}
if(mi==INF) printf("-1");
else write(mi*n+ans);
putchar('\n');
}
lyx AKIOI;
}