1352 集合计数(求解的个数)

来源:互联网 发布:兰印婚礼知乎 编辑:程序博客网 时间:2024/06/05 11:55

1352 集合计数
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注
给出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

题解:用扩展欧几里得的公式求解的个数,首先要求出一个最小解,然后找到a和b 的最小公倍数,然后一个莫名其妙的原理就可以解出来了

#include <cstdio>#include <cstring>#include <math.h>#include <algorithm>using namespace std;#define LL long long#define MOD 1000000007#define M 200010#define INF 0x3f3f3f3fLL n;LL exgcd(LL a, LL b, LL &d, LL &x, LL &y){    if(!b)    {        d = a;        x = 1;        y = 0;    }    else    {        exgcd(b, a%b, d, y, x);        y -= x * (a / b);    }}int main(){    int t;    LL x, y, k, d, a, b, bl, xm, ym, al, num;    scanf("%d", &t);    while(t--)    {        scanf("%lld%lld%lld", &n, &a, &b);        exgcd(a, b, d, x, y);        n++;        k = n / d;        if(n % d != 0)        {            printf("0\n");            continue;        }        else        {            bl = b / d, al = a / d;            xm = (x*k%bl + bl) % bl;            LL lc = a * b / d;//最小公倍数            if(xm == 0)            {                xm = bl;//最小的正数解            }            num = 0;            LL remain = n - 1 - xm * a;//求出余下的值,这里注意n 要减去 1,或许因为已经有了一组解            if(remain >= 0)//因为n减去了1,所以余下的值等于0的话也无所谓            {                num = 1;                num += remain / lc;//余下的值除以最小公倍数            }        }        printf("%lld\n", num);    }    return 0;}
0 0
原创粉丝点击