列出等式之后 发现是二元一次不定式 求正整数解 然而并不会求解 枚举肯定超时 经过一番搜索 发现是扩展欧几里德 然后现学现卖了一下
然而边界问题 涉及到四个实数化整 并求交集 需要考虑的太多 一时考虑不清楚 决定暴力枚举 然后只过了一半数据 只好又回头处理边界问题 静下心来 仔细一思考 边界问题也并不是那么难处理
给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数。
提示:
对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个。
Input
第1行:1个整数T(1<=T<=50000),表示有多少组测试数据。 第2 - T+1行:每行三个整数N,A,B(1<=N,A,B<=2147483647)
OutPut
对于每组测试数据输出一个数表示满足条件的集合的数量,占一行。
Input示例
2 5 2 4 10 2 3
Output示例
1 2
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = 1100;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);
#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)
ll gcd (ll a, ll b)
{
return b ? gcd (b, a % b) : a;
}
ll extgcd (ll a, ll b, ll &x, ll &y)
{
ll d = a;
if (b != 0)
{
d = extgcd (b, a % b, y, x);
y -= (a / b) * x;
}
else
x = 1, y = 0;
return d;
}
int main ()
{
int t;
cin >> t;
while (t--)
{
ll n, a, b, d, x, y;
cin >> n >> a >> b;
d = gcd (a, b);
if ((n + 1) % d != 0)
{
cout << 0 << endl;
continue;
}
extgcd (a, b, x, y);
ll x1, y1;
double k1, k2, k3, k4;
ll tk1, tk2, tk3, tk4;
x1 = x * (n + 1) / d;
y1 = y * (n + 1) / d;
k1 = 1.0 * d * (1 - x1) / b;
tk1 = (ll)k1;
if (x1 + b / d * tk1 < 1) tk1++;
k2 = 1.0 * d * (n + 1 - x1) / b;
tk2 = (ll)k2;
k3 = 1.0 * d * (y1 - 1) / a;
tk3 = (ll)k3;
if (y1 - a / d * tk3 < 1) tk3--;
k4 = 1.0 * d * (y1 - n - 1) / a;
tk4 = (ll)k4;
if (tk1 - tk3 > 0 || tk4 - tk2 > 0)
cout << 0 << endl;
else
{
ll xx = max (tk1, tk4);
ll yy = min (tk2, tk3);
if (yy < xx) cout << 0 << endl;
else
cout << yy - xx + 1 << endl;
}
}
return 0;
}