zoukankan      html  css  js  c++  java
  • [WC2020] 猜数游戏 题解

    一个(O(n^2log))垃圾做法

    考虑建出一张有向图(G,) 有边(i->j)当且仅当存在一个正整数(m)使得(a_i^m)(a_j)在模(p)意义下同余(,)然后在图(G)上计算答案(.)

    Part1:建图

    subtask1:模数为奇质数

    (p)意义下存在原根(,)设为(g.)

    那么每个(a_i)都可以表示成(g^{k_i})

    考虑求出一个数(a_i)的指标和(phi(p))(gcd)的值(k_i(k_i|phi(p)):)

    显然(k_i)为满足(a_i^{phi(p)/k})(p)之后为(1)的最大的数(.)

    枚举每个质因数(p)求它的次数(,)这个工作就可以在(O(d(phi(p)) imes log p)) 的时间内完成(.)

    那么(,) (i->j)存在当且仅当(k_i|k_j.)

    这样就可以(O(1)) (check)是否存在边(i->j)

    subtask2:模数为奇质数(q)(t(t>1))次幂

    (p^k)意义下也存在原根(.)

    不难发现我们可以用同样的方法求出所有(k_i,)但是这回一个数可能会是(q)的倍数(,)我们记(a_i)的因数分解中存在的(q)的个数为(m_i.)

    这次我们怎么(check) (i->j)是否可以连边呢(?)

    首先如果(m_i=m_j=0,)那么就直接用上一个(subtask)的做法即可(.)

    如果有一个(m=0,)而另一个(m ≠ 0,)那么边(i->j)不存在(.)

    如果(m_i≠0,m_j≠0,)那么我们可以直接计算出可能使(a_i^z=a_j)的数字(z,z=m_j/m_i,)然后直接快速幂解决(.)

    那么就可以(O(log p))的复杂度内(check)是否存在边(i->j)

    如果害怕(T)飞的话可以求出原根用光速幂(,)不过(O(n^2log p))实际情况下也能过(.)


    Part2:计算答案

    建出图之后(,)我们考虑怎么计算答案(.)

    考虑一个(a_i)对答案的贡献(.)

    有一个想法是(a_i)在答案中存在的条件为当且仅当没有任何数能够表示出它(,)记这些数的个数为(cnt,)那么(a_i)对答案的贡献就是(2^{cnt}.)

    但是这样做忽略了环的情况(,)只能获得(10pts.)

    举个例子(,)如果(n=2,)(G)中存在边((1,2),(2,1),)如果按照这种算法计算出来的答案就是(2,)而正确答案是(3.)

    那么这个问题怎么解决呢(?)

    不难发现如果有一个强联通分量(S,) (S)内部的所有点必然是能两两连边的(,)所以我们可以给一个强联通分量内的点强制一个顺序(,)就可以正确的计算出答案了(.)

    代码(:) 见云剪贴板


    Bonus:如何解决(nleq 10^5,pleq 10^{18})

    首先求出(phi(p),)(pollard-rho)分解质因数(,)并爆搜出(phi(p))的因子(.)

    对于(gcd(a_i,p)≠1)(a_i)的贡献(,)

    可以直接(O(nlog p imes K))暴力解决(,)其中(K)(phi(p))的质因数个数(.)

    对于(gcd(a_i,p)=1)的数字(,)

    首先用(O(nlog p imes K))的复杂度算出这(O(n))个数的指标(,)

    然后以这些因子为下标运行狄利克雷前缀和即可(.)

    复杂度(O(nlog p imes K + d(phi(p)) imes K))

    代码(:) 见云剪贴板

  • 相关阅读:
    CGI, FCGI, SCGI, WSGI 释异
    Boa Web Server 缺陷报告及其修正方法
    2.1 linux C 进程与多线程入门--(1)进程和程序的区别
    利用socket实现双机通信
    1、进程管理
    第一章:进程与线程总结
    8、linux网络编程--多播
    6、linux网络编程--UDP协议编程
    7、linux网络编程--广播
    4、linux网络编程--套接字的介绍
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13581312.html
Copyright © 2011-2022 走看看