【NOIP2018复习】A (数论、线性求逆元)

A

时间限制:5000MS内存限制:256000KB

题目描述

 HJW发明了一种神奇的排序方法。有了这个方法,对于任意数列,排序的复杂度为把该序列变从小到大排序最少交换的次数。询问对于n的任意一个排列,排序的复杂度期望。
 

输入

从文件 inverse.in 中读入数据。
输入第一行包含一个正整数 T ,表示数据组数。
对于每组数据,第一行有一个正整数n。

输出

输出到文件 inverse.out 中。
输出共 T 行,每行一个整数。
对于每组数据,输出一个整数,表示答案对 998244353 取模的结果。

输入样例复制

2
2
3

输出样例复制

499122177
166374060
当n=2,排列为{1,2}和{2,1},交换次数为0和1,期望为1/2。
当n=3,排列为{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1},交换次数为0,1,1,2,2,1,期望为7/6。

说明

对于20%的数据,T<=10,n<=10; 对于另外20%的数据,T=1; 对于另外10%的数据,n<=10^3; 对于100%的数据,T<=10^5,n<=10^7。
 

 题解: 推导最小交换次数:将数字与最终所处位置的下标连线,得到k个环,则最小交换次数为n-k

            如 6 4 2 1 3 5                                                                 3 4 2 1 5 6
             1-4-2-3-5-6-1  最小交换 6-1=5                                      1-4-2-3-1     5-5  6-6  最小交换6-3=3
           设f[n]为n个数的期望环数量,对于f[n-1]已知,第n个数有n个空隙可以插入,且只有插入队尾可以得到一个新的环
           所以f[n]=f[n-1]+1/n;
          答案为n-sigma(1-n,1/i)
          1/i即i的逆元,根据费马小定理,在模意义下i的逆元为i^(p-2)
          因为快速幂复杂度为根号n,所以问题转化为线性求逆元
          线性求逆元公式: a[i]:=(p-(p div i))*a[p mod i]mod p             a[1]=1

const

  maxn=10000000;

  p=998244353;

var

  a,sum:array[1..maxn]of int64;

  n,i,t:longint;

procedure init;

var

  i:longint;

begin

  a[1]:=1;

  for i:=2 to maxn do

    a[i]:=(p-(p div i))*a[p mod i]mod p;

  sum[1]:=a[1];

  for i:=2 to maxn do

    sum[i]:=(sum[i-1]+a[i])mod p;

end;

begin

  init;

  readln(t);

  for i:=1 to t do

  begin

    readln(n);

    writeln((n-sum[n]+p)mod p);

  end;

end.

 

你可能感兴趣的:(数论)