• 【UOJ#22】【UR#1】外星人


    2044年,Picks建成了人类第一台基于量子理论的银河系信息传递机。

    Picks游遍了宇宙,雇用了 n 个外星人来帮他作为信息传递机的中转站。我们将外星人依次编号为 1 到 n,其中 i 号外星人有 ai 根手指。

    外星人都是很低级的,于是Picks花费了很大的精力,才教会他们学会扳手指数数。

    Picks现在准备传递 x 个脉冲信号给VFleaKing,于是他把信号发给1号外星人,然后1号外星人把信号发送给2号外星人,2号外星人把信号发送给3号外星人,依次类推,最后n号外星人把信号发给VFleaKing。

    但是事情没有Picks想象的那么顺利,由于外星人手指个数有限,所以如果 i 号外星人收到了 t 个脉冲信号,他会错误的以为发送过来的是 mod ai 个脉冲信号,导致只发送了t mod ai 个脉冲信号出去。

    Picks希望他发送出去的脉冲信号数量 x 与VFleaKing收到的脉冲信号数量 y 的差的绝对值尽量小。于是他决定通过重新排列这些外星人的顺序来达到这一目的。请你求出与 x 之差最小的 y。除此之外,请求出有多少种排列外星人的方式能达到最优解,你只需要输出方案数对 9982443537×17×223+17×17×223+1,一个质数)取模后的结果。

    n1000,x,ai5000

    vfk讲得很详细了我就不重复了(其实是根本没懂QAQ

    http://vfleaking.blog.uoj.ac/blog/33

    这题细节好多,我抄po姐的代码都能debug两个小时QAQ,思维实在是不细致……

    我这么弱怎么办嘛QAQ

    值得注意的是线筛求逆元……

    (图片来自syq

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long
     8 const int mo=998244353;
     9 int rd(){int z=0,mk=1;  char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    11     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    12     return z*mk;
    13 }
    14 int n,m,a[1100];
    15 ll jj[5100],hh[5100];
    16 int f[5100],cnt[5100];  ll g[5100];
    17 void gtjj(){
    18     jj[0]=1;
    19     for(int i=1;i<=5000;++i)  jj[i]=jj[i-1]*i%mo;
    20     hh[1]=1;
    21     for(int i=2;i<=5000;++i)  hh[i]=(mo-mo/i)*hh[mo%i]%mo;
    22     hh[0]=1;
    23     for(int i=1;i<=5000;++i)  hh[i]=hh[i]*hh[i-1]%mo;
    24 }
    25 int main(){freopen("ddd.in","r",stdin);
    26     cin>>n>>m;  gtjj();
    27     for(int i=1;i<=n;++i)  a[i]=rd();
    28     sort(a+1,a+n+1);
    29     g[0]=1;
    30     for(int i=1,k=1;i<=m;++i){
    31         while((a[k]<=i)&(k<=n))  ++k;
    32         cnt[i]=k-1;
    33         if(!cnt[i])  f[i]=i,g[i]=1;
    34         else
    35             for(int j=1;j<=cnt[i];++j){
    36                 if(f[i%a[j]]>f[i])  f[i]=f[i%a[j]],g[i]=0;
    37                 if(f[i%a[j]]==f[i])
    38                     g[i]=(g[i]+jj[cnt[i]-1]*hh[cnt[i%a[j]]]%mo*g[i%a[j]]%mo)%mo;
    39             }
    40     }
    41     cout<<f[m]<<endl;
    42     cout<<jj[n]*hh[cnt[m]]%mo*g[m]%mo<<endl;
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    python使用数据库的一些操作
    正则表达式整理
    tomcat启动成功但是访问不到官网
    控制反转 依赖注入 AOP 和 IOC
    abstract 和 interface区别
    input文本框 鼠标点击默认消失,不输入离开鼠标恢复默认值
    声明式管理事务:基于AspectJ的xml方式
    使用注解配置声明式事务
    spring事物 (mu课)
    oracle表之数据类型
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6900823.html
Copyright © 2020-2023  润新知