20181005提高测试

T1

【错解】

首先猜想和最大值有关,然而样例都凑不出来

然后开始瞎搞,从大往小拆成两个没出现过的数的乘积

过了样例……

等等?好像最大有重复的?

然后真瞎搞

WA1+TLE9

期间想到二分,但并不知道怎么check,索性放弃

【正解】

二分

由于是阶乘,x!某个因数a出现次数为

(sum _{i=1}^{infty} [frac{x}{a^{i}}])

把读入的数分解,然后就可以check辣

code

T2:上升序列
(lis)
【问题描述】
给出一个长度为 m 的上升序列 A(1 ≤ A[i]≤ n), 请你求出有多少种 1...n 的排列, 满足
A 是它的一个 LIS.
【输入】
第一行两个整数 n,m.
接下来一行 m 个整数, 表示 A.
【输出】
一行一个整数表示答案.
【输入样例1】
5 3
1 3 4
【输出样例1】
11
【输入样例2】
4 2
3 4
【输出样例2】
5
【数据范围与约定】
对于前 30% 的数据, n ≤ 9;
对于前 60% 的数据, n ≤ 12;
对于 100% 的数据, 1 ≤ m ≤ n ≤ 15.

【错解】

一看数据范围就知道是暴搜

发现没有规律,怒写了个nlogn暴力check

用链表维护

没有减掉枝

AC6+TLE4

【正解】

为什么不能状压呢

首先回忆nlogn求法:

定义d[i]为长度为i结尾最小的子序列,然后二分插入来转移

即nlogn求时最后的那个数组

当然不是这么做的

设状态s表示选了那些数,s1表示d中哪些数出现了

举个生动形象的栗子:2 3 1 4……

s={1,1,1,1,0}

d={1,3}

s1={1,0,1,0,0}

因为d是单调增的,所以我们可以用s1来还原d

即如果s1[i]为1,那么i在d中出现的位置为1~i的1的个数

然后可以(f(s,s1))定义状态

然后枚举插入一个数,就可以转移了

具体操作:插入i时,前面有k位

s|=i

s1前k位转成d,再把后面接上

如在3、1之间插入5

s={1,1,1,1,1}

s1不变

边界:当s为全集时,(f(s,s1)=(d长度为原序列长度))

然而复杂度不可接受

观察发现s1为s子集

所以可以三进制表示:0表示都不在,1表示在s不在s1,2表示既在s又在s1

然后可以AC此题

[代码待补]

T3

【错解】

woc提高考树剖?还没法维护?

骗分,放弃

WA10

【正解】

一个结论:树上两条路径有交集,当且仅当其中一条路径的LCA在另一条路径上

然后就转化为:

单点修改,路径查值

路径修改,单点查值

然后直接上树链……什么?被卡了?

考虑路径可以转换为4个点到根路径,做个类似于树上前缀和的玩意

然后直接上树剖

因为是单点查值,到根路径对其有影响当且仅当在其子树上

然后成了子树 树状数组维护dfs序即可

[代码待补]

原文地址:https://www.cnblogs.com/lstoi/p/9745073.html