【CF补题&&数学&&裴蜀定理】 div969 C Dora and C++ ...

打印 上一主题 下一主题

主题 991|帖子 991|积分 2973

Dora and C++



分析:

对于两个数x,y
我们想要通过如下操作使得他们的差变得尽可能小
我们要如何操作?
这个操作也就是相当于                                   d                         e                         l                         =                         ∣                         y                         −                         x                         ∣                         −                                   k                            1                                  ∗                         x                         −                                   k                            2                                  ∗                         y                              del=|y-x|-k_1*x-k_2*y                  del=∣y−x∣−k1​∗x−k2​∗y,让这个差值最小
对于                                             k                            1                                  ∗                         x                         +                                   k                            2                                  ∗                         y                              k_1*x+k_2*y                  k1​∗x+k2​∗y这个操作
根据裴蜀定理,我们知道                                             k                            1                                  x                         +                                   k                            2                                  y                         =                         k                         ∗                         g                         c                         d                         (                         x                         ,                         y                         )                              k_1x+k_2y=k*gcd(x,y)                  k1​x+k2​y=k∗gcd(x,y)
也就是说通过这个操作得到的数,一定是                                   g                         c                         d                         (                         x                         ,                         y                         )                              gcd(x,y)                  gcd(x,y)的倍数
那么,                                   M                         i                         n                         (                         d                         e                         l                         )                         =                         ∣                         y                         −                         x                         ∣                         %                         g                         c                         d                              Min(del)=|y-x|\%gcd                  Min(del)=∣y−x∣%gcd
我们对上式的                                   x                         ,                         y                              x,y                  x,y用另一种情势表示:
                                    x                         =                         X                         +                                   k                            x                                  g                         c                         d                              x=X+k_xgcd                  x=X+kx​gcd
                                    y                         =                         Y                         +                                   k                            y                                  g                         c                         d                              y=Y+k_ygcd                  y=Y+ky​gcd
                                    ∣                         y                         −                         x                         ∣                         =                         ∣                         Y                         −                         X                         +                         (                                   k                            y                                  −                                   k                            x                                  )                         g                         c                         d                         ∣                              |y-x|=|Y-X+(k_y-k_x)gcd|                  ∣y−x∣=∣Y−X+(ky​−kx​)gcd∣
经过                                   m                         o                         d                              mod                  mod意义之后,其实                                   ∣                         y                         −                         x                                   ∣                                       m                               i                               n                                            =                         ∣                         Y                         −                         X                         ∣                              |y-x|_{min}=|Y-X|                  ∣y−x∣min​=∣Y−X∣
其实就是说,x和y在这个条件下可以等价于                                   x                         %                         g                         c                         d                         以及                         y                         %                         g                         c                         d                              x\%gcd以及y\%gcd                  x%gcd以及y%gcd
他们的差值最小值也就是取模意义之后两数的差的绝对值
那么对于这道题而言,最小的差值就是每个数                                   M                         o                         d                                                   g                         c                         d                              Mod\ gcd                  Mod gcd意义下的极差。
但是其实并不完全。
比如取模意义后两个数变成0和2,而gcd=3
实际上可以让0+3,再和2去做差
这个其实就类似于一个环形的标题
跨越之后可能让差值更小

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int N = 2e5+100;
  5. int n,x,y;
  6. int a[N];
  7. int gcd(int x,int y){
  8.         return y == 0?x:gcd(y,x%y);
  9. }
  10. void Work(){
  11.         cin>>n>>x>>y;
  12.         int g = gcd(x,y);
  13.         for (int i = 1; i <= n; i++) cin>>a[i],a[i]%=g;
  14.         sort(a+1,a+n+1);
  15.         for (int i = n+1; i <= 2*n; i++) a[i] = a[i-n]+g;
  16.         int Min = 1e9+7;
  17.         for (int i = 1; i <= n+1; i++)
  18.           Min = min(Min,a[i+n-1]-a[i]);
  19.         cout<<Min<<endl;
  20.         return;
  21. }
  22. signed main(){
  23.         int t; cin>>t;
  24.         while (t--) Work();
  25.         return 0;
  26. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

风雨同行

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表