51nod 1352 集合计数(扩展欧几里得)

题目链接:传送门

题意:略

分析:

非常easy能够得到一个方程 A*x + B*y = N + 1

这式子能够用扩展GCD求出gcd,x和y,然后我们求出大于0的最小x,A*x第一个满足条件的集合firstSet,剩下的N-firstSet个集合能够直接除LCM(A,B)(A和B的最小公倍数)统计出数量。

代码例如以下:

#include <stdio.h>
#include <string.h>
#include <iostream>
#define LL long long
using namespace std;
LL exgcd(LL a, LL b, LL &x, LL &y) {
    LL r,t;
    if(b==0) {
        x=1;
        y=0;
        return a;
    }
    r=exgcd(b,a%b,x,y);
    t=x;
    x=y;
    y=t-a/b*y;
    return r;
}
int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        LL ans = 0;
        LL N, A, B;
        LL xx,yy,d,r;
        scanf("%I64d%I64d%I64d",&N, &A, &B);
        d=exgcd(A, B, xx, yy);
        if(((N + 1) % B) % d != 0) ans = 0;
        else {
            LL lcm = A * B / d;
            xx = xx *(((N + 1) % B) / d);
            r = B / d;
            xx=(xx % r + r) % r;
            if(xx == 0) {
                xx = lcm / A;
            }
            if(xx * A > N) {
                ans = 0;
                printf("%I64d\n", ans);
                continue;
            }
            ans += ((N - xx * A) / lcm);
            ans++;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
时间: 2024-11-09 06:02:50

51nod 1352 集合计数(扩展欧几里得)的相关文章

51nod 1352 集合计数

给出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

51Nod 1256 乘法逆元(扩展欧几里得)

1 #include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 typedef long long LL; 6 7 //给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b) 8 LL extgcd(LL a, LL b, LL &x, LL &y){ 9 LL d = a; 10 if (b != 0){ 11 d = extgcd(b, a%b,

[ACM] hdu 3923 Invoker (Poyla计数,高速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

[ACM] hdu 3923 Invoker (Poyla计数,快速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

扩展欧几里得(ex_gcd),中国剩余定理(CRT)讲解 有代码

扩展欧几里得算法 求逆元就不说了. ax+by=c 这个怎么求,很好推. 设d=gcd(a,b) 满足d|c方程有解,否则无解. 扩展欧几里得求出来的解是 x是 ax+by=gcd(a,b)的解. 对于c的话只需要x*c/gcd(a,b)%(b/d)即可,因为b/d的剩余系更小. 为什么这样呢? 设a'=a/d,b'=b/d 求出a'x+b'y=1的解,两边同时乘d,然后x也是ax+by=d的解, 然后因为b'的剩余系更小,所以%b’ 中国剩余定理是合并线性方程组的 中国余数定理 转化为一个线性

exgcd扩展欧几里得求解的个数

知识储备 扩展欧几里得定理 欧几里得定理 (未掌握的话请移步[扩展欧几里得]) 正题 设存在ax+by=gcd(a,b),求x,y.我们已经知道了用扩欧求解的方法是递归,终止条件是x==1,y==0: int exgcd( int a, int b, int &x, int &y ) { if( b == 0 ) { x = 1; y = 0; return a; } int tmp = a % b; if( tmp > b ) swap( tmp, b ); int ans=exg

UVa 11768 格点判定(扩展欧几里得求线段整点)

https://vjudge.net/problem/UVA-11768 题意: 给定两个点A(x1,y1)和B(x2,y2),均为0.1的整数倍.统计选段AB穿过多少个整点. 思路: 做了这道题之后对于扩展欧几里得有了全面的了解. 根据两点式公式求出直线 ,那么ax+by=c 中的a.b.c都可以确定下来了. 接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数. 需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b

【扩展欧几里得】BZOJ1477-青蛙的约会

一直在WA,后来我发现我把东西看反了-- [题目大意] 给出一个长度为L的环状坐标轴,两个点开始时位于(X,0).(Y,0).每次两点分别往右边移动m和n,问能否相遇? [思路] 由题意,可得: X+mt=Y+nt(mod L) (X+mt)-(Y+nt)=L*k (n-m)t+L*k=X-Y. 可以用扩展欧几里得来做.具体来说,显然要满足n-m和L的最大公约数(记为d)要整除X-Y,否则无解.这个可以在扩展欧几里得中求出. 式子可以化简为:[(n-m)/d]*t+(L/d)*k=(X-Y)/d

POJ 1061 青蛙的约会 扩展欧几里得

扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; ll exgcd(ll a, ll b, ll&x, ll&y) { if (b ==