5.29模拟赛

来源:互联网 发布:nginx加tomcat 编辑:程序博客网 时间:2024/06/15 01:13

5.29模拟赛


第一题:sum

题目描述:
求有多少N 位十进制数是P 的倍数且每位之和小于等于M,允许前导0,答案对998244353 取模。

输入格式:
一行三个整数N,P,MM。MM 的含义见输出格式。
输出格式:
一行输出MM+1 个整数,第i个(从0 开始)表示M=i 时的答案

样例输入:
2 3 3

样例输出:
1 1 1 5

数据规模与约定:

 对于测试点1:1<=N<=1000.1<=P<=50.1<=MM<=5  对于测试点2,3:1<=N<=10^9.1<=P<=50.1<=MM<=5  对于测试点4,5,6:1<=N<=10^9.1<=P<=50.1<=MM<=50  对于测试点7,8,9,10:1<=N<=10^9.1<=P<=16.1<=MM<=1000 

题解:

10分:
f[i][j][k]表示一个i位的数字,mod P为j,各位的和为k的方案数。
枚举在最后加上一个数字x,去更新f[i+1][(j×10+x)modP][k+x]

30分:
矩阵快速幂优化dp转移。

60分:
倍增优化dp转移。
f[i][j][k]表示2i位,mod P为j,各位的和为k的方案数。
我们可以用两个长度为2i的拼成一个长度为2i+1的。
具体来说,就是:

f[i+1][j1×102i+j2][k1+k2]=(f[i][j1][k1]×f[i][j2][k2])

怎么得到答案:长度为n的呢?
仿照上面的原理,合并两个长度为长度为
求出f来之后选择一些组合一下得到答案。
选那些f呢?就像快速幂一样,用n的二进制是1的位对应的f统计答案。
(其实和上面的原理一样,只不过这里合并的两段的长度不相等)
设g[2][j][k]表示答案,假如n的二进制第i位是1,则:
g[nxt][j1102i+j2][k1+k2]=(g[now][j1][j2]×f[i][j2][k2])

答案是:g[now][0][m].

100分:
NTT优化倍增。
不会。。。

Code:

//NULL

第二题:set

题目描述:
给出n 个非负整数,将数划分成两个集合,记为1号集合和2 号集合。x1
为1号集合中所有数的异或和,x2 为2 号集合中所有数的异或和。在最大化
x1+x2 的前提下,最小化x1。

输入格式:
第一行包含一个整数n。第二行包含n 个用空格隔开的数字,保证它们都
是不超过10^18 的非负整数。

输出格式:
输出一行一个数,表示最优方案中的x1。

样例输入:
8
1 1 2 2 3 3 4 4

样例输出:
7

数据规模与约定:

 对于30%的数据,保证n<=10;  对于60%的数据,保证n<=1000;  对于100%的数据,保证n<=100000。 

题解:

30分:
暴力枚举。

60分:
假设ALL是所有数的抑或和,比如ALL=100110……
对于ALL中是1的位,不管怎么分,一定是一个集合这一位是1,另一个这一位是0。
对于ALL中是0的位,两种情况,两个集合的这一位分别是(1,1)或者(0,0),我们当然希望是(1,1)。
为了使x1+x2最大,我们要先考虑第二种是0的位,尽量拆成(1,1);然后再考虑是1的位,尽量让x1这一位是0,x2是1。
等价于 先考虑0的位,尽量让x2是1(此时x1也一定是1);再考虑是1的位,尽量让x2是1(此时x1是0)。
这就很像线性基了,只不过枚举位的顺序是先ALL里是0的从高到低,再1的从高到低。

100分:
不会。。。

Code:

//NULL