但扩欧肯定能做,有题解为证:link
然后我就调吐了还只有50分。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return a;
}
int nx,ny;
int g=exgcd(b,a%b,nx,ny);
x=ny;
y=nx-a/b*ny;
return g;
}
int tx1[100005],ty1[100005],tx2[100005],ty2[100005];
int c1,c2,c3,c4,n;
int pos[100005],len;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>c1>>c2>>c3>>c4>>n;
int g1=__gcd(c1,c2),g2=__gcd(c3,c4);
int addx1=c2/g1,addy1=-c1/g1,addx2=c4/g2,addy2=-c3/g2;
set<int>acp;
for(int i=0;i<=100000;i++){
if(i%g1>0)continue;
exgcd(c1,c2,tx1[i],ty1[i]);
tx1[i]*=(i/g1);
ty1[i]*=(i/g1);
if(i%g2>0)continue;
exgcd(c3,c4,tx2[i],ty2[i]);
tx2[i]*=(i/g2);
ty2[i]*=(i/g2);
acp.insert(i);
}
for(auto x:acp)pos[++len]=x;
while(n--){
int d1,d2,d3,d4,s;
cin>>d1>>d2>>d3>>d4>>s;
int sum=0;
for(int l=1;l<=len;l++){
int i=pos[l];
if(i>s)continue;
int x0=tx1[i],y0=ty1[i];
int xl=0,xr=d1,yl=0,yr=d2;
int xkl,xkr,ykl,ykr;
if(addx1>0){
xkl=ceil(1.0*(xl-x0)/addx1),xkr=floor(1.0*(xr-x0)/addx1);
}else{
xkl=ceil(1.0*(xr-x0)/addx1),xkr=floor(1.0*(xl-x0)/addx1);
}
if(addy2>0){
ykl=ceil(1.0*(yl-y0)/addy1),ykr=floor(1.0*(yr-y0)/addy1);
}else{
ykl=ceil(1.0*(yr-y0)/addy1),ykr=floor(1.0*(yl-y0)/addy1);
}
int kl=max(xkl,ykl),kr=min(xkr,ykr);
if(kl>kr||xkl>xkr||ykl>ykr)continue;
int res=(kr-kl+1);
x0=tx2[s-i],y0=ty2[s-i];
xl=0,xr=d3,yl=0,yr=d4;
if(addx2>0){
xkl=ceil(1.0*(xl-x0)/addx2),xkr=floor(1.0*(xr-x0)/addx2);
}else{
xkl=ceil(1.0*(xr-x0)/addx2),xkr=floor(1.0*(xl-x0)/addx2);
}
if(addy2>0){
ykl=ceil(1.0*(yl-y0)/addy2),ykr=floor(1.0*(yr-y0)/addy2);
}else{
ykl=ceil(1.0*(yr-y0)/addy2),ykr=floor(1.0*(yl-y0)/addy2);
}
kl=max(xkl,ykl),kr=min(xkr,ykr);
if(kl>kr||xkl>xkr||ykl>ykr)continue;
res*=(kr-kl+1);
sum+=res;
}
cout<<sum<<"\n";
}
}
事实证明这题用扩欧做就是石。