• 【ZJOI2017 Round1练习&BZOJ4766】D1T2 文艺计算姬(Prufer编码)


    题意:给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},求其生成树个数 mod p。

    100%的数据:1 <= n,m,p <= 10^18

    思路:这是一道结论(打表找规律)+教你快速幂和乘法 题

    结论为:S=n^(m-1)*m^(n-1)

    需要注意的是n,m过大,普通的快速幂与乘法会炸

    所以需要手写乘法,类似于快速幂的形式将其转换为加法

    2017.2.28:%%%CC的证明:

    设两边为X侧,Y侧

    考虑它们在Prufer序列中出现的位置与取值种数

    生成树的最后一条边一定链接一个X侧一个Y侧点

    一个X侧点的插入就代表一个Y侧点被删除

    因为最后只剩一个X侧点一个Y侧点

    所以X侧点会出现M-1次,每次出现有N种取值,每个X侧点可以重复出现

    所以对于X侧点有n^(m-1)种取值

    Y侧点同理

    得证

     1 var n,m,mo:int64;
     2 
     3 function clac(x,y:int64):int64;
     4 begin
     5  clac:=0;
     6  while y>0 do
     7  begin
     8   if y and 1=1 then clac:=(clac+x) mod mo;
     9   x:=(x+x) mod mo;
    10   y:=y>>1;
    11  end;
    12 end;
    13 
    14 function mult(x,y:int64):int64;
    15 begin
    16  mult:=1;
    17  while y>0 do
    18  begin
    19   if y and 1=1 then mult:=clac(mult,x) mod mo;
    20   x:=clac(x,x) mod mo;
    21   y:=y>>1;
    22  end;
    23 end;
    24 
    25 begin
    26  assign(input,'art.in'); reset(input);
    27  assign(output,'art.out'); rewrite(output);
    28  readln(n,m,mo);
    29  writeln(clac(mult(n,m-1),mult(m,n-1)));
    30  close(input);
    31  close(output);
    32 end.
  • 相关阅读:
    EasyUI问题小结(不定期更新·······)
    windows服务与前台交互
    C#捕获Windows窗体控件
    C#操作AD域中计算机
    远程桌面 Rdp文件的生成
    正则匹配的例子
    Nodejs中npm install 命令的问题
    Windows下使用curl命令
    关于PostmanURL中不能传递中文的问题
    MyBatis_Study_004(动态代理)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6478689.html
Copyright © 2020-2023  润新知