AtCoder GC 018A: Getting Difference 题解

来源:互联网 发布:nodejs 多个js 编辑:程序博客网 时间:2024/05/21 17:20

可以无限制的两两做差,这让人想到了一个东西:辗转相减法求最大公约数

假设这n个数的最大公约数是g,那么ai可以表示为bi*g,所以任意两两相减得到的所有结果都是g的倍数

这所有的bi中一定存在一组bi和bj,满足gcd(bi,bj)=1,否则g就不是最大公约数了

那么由exgcd得,ax+by=gcd(a,b)有整数解,所以盯着这组gcd=1的bi,bj做辗转相减,一定可以得到g

有了g,那么拿着所有数中的最大数不停地减g,就可以得到小于等于max的所有g的倍数

总之,这些数任意两两相减所得结果的集合,就是不大于max的所有的g的倍数

只要k<=max且k%g=0,就是possible,否则是impossible

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std; const int MOD=1e9+7;const int INF=1e9;const int magic=348; int n,k;int a[100048]; int gcd(int x,int y){return y==0?x:gcd(y,x%y);} int main (){int i;scanf("%d%d",&n,&k);int maxn=-1;for (i=1;i<=n;i++) {scanf("%d",&a[i]);maxn=max(maxn,a[i]);}if (k>maxn){printf("IMPOSSIBLE\n");return 0;}int g=a[1];for (i=2;i<=n;i++) g=gcd(g,a[i]);if (k%g==0) printf("POSSIBLE\n"); else printf("IMPOSSIBLE\n");return 0;}


原创粉丝点击