题目链接:https://www.zhixincode.com/contest/29/problem/J
题目大意:和纱每b天休息前a天,后面开演唱会,雪菜每d天工作前c天,后面休息,问她在n天中有多少天有空看演唱会
div2中的数据范围比较小,可以n方循环可行天数用类欧解答
(i,j)表示和纱的可行区间中第i天 雪菜的可行区间的第j天重合
用x表示和纱在第一个区间后又进行了几个区间,y表示雪菜在第一个区间后又进行了几个区间
那么: i+bx=j+dy 不定方程就出来了
可以用类欧解最小解,然后求得循环节(x的通解)算出在n内有多少满足条件的解
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
void exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return;
}
exgcd(b,a%b,x,y);
int tem=x;
x=y;y=tem-a/b*y;
}
int main()
{
//cout<<__gcd(3,-6)<<endl;
//cout<<(-3)%2<<endl;
ios::sync_with_stdio(false);
int t;
int a,b,c,d;
int x,y;
cin>>t;
while(t--)
{
ll n,sum=0;
cin>>a>>b>>c>>d>>n;
for(int i=a+1;i<=b;i++)
{
for(int j=c+1;j<=d;j++)
{
int aa=b,bb=-d,dd=j-i;
//aa*x+bb*y=dd
int g=__gcd(aa,bb);
if(dd%g!=0)//不定方程无解
{
continue;
}
aa/=g,bb/=g,dd/=g;
exgcd(aa,bb,x,y);//得到的x是 ax+by=gcd的一组解
bb=abs(bb);
//x的通解为x0+t*bb
x=((1ll*x*dd)%bb+bb)%bb;//最小解x
//这里的最小解是第一个区间的后x个区间 i和j重合
if(i>n||((n-i)/b)<x)//非法
{
continue;
}
sum+=((n-i)/b-x)/bb+1;//第一个+剩余在n中存在的循环节数
}
}
cout<<sum<<endl;
}
return 0;
}