北京Day 7

极其毒瘤的一天,全场十几个人爆零(包括我)。

这里放一下题解。(由于题目过于毒瘤+填坑+加强自己出的题的数据并没有写代码)

T1

题目大意:有若干堆石子,要求每次在一堆数量不为1的石子堆中取出石子,假设这堆石子的个数是x,那么允许取的个数为正整数d,要求d|x且d≠x,没法再取石子的一方输。 游戏初始有m堆石子,每堆石子的个数均为1到n之间的正整数。问有多少种可能的初始状态先手一定能获胜(认为石子堆是有顺序的),答案模998244353。 n<=10^50000,m<=10^18。

用数学归纳法(打表)发现 k 个石子组成的一堆 SG 值为 k 能够整除的 2 的最高次幂

对于n, m ≤ 52501,用一个简单的 DP 即可计算出答案。

对于n, m ≤ 10^18,容易发现上面的 DP 可以改成倍增 DP。

当 n 很大时,我们首先要用高精度计算出 1 到 n 中包含 2 的最高次 幂为 k 的个数,我们发现此时 log n 也达到了 3e5 级别,需要优化倍增 DP 的转移。高精度可能需要压位来提高效率

我们自然想到可以用 FWT 优化计算,倍增计算时直接用 FWT 的点积相乘即可。

T2

题目大意:一个长度为n 的序列由一个1到9的数字组成。q次操作:

操作1:选择一个子串[L,R],从这个子串中再次随机选择一个子串,答案等于把子串转成十进制数字的期望。

操作2:把子串子串[L,L+x] 用子串[R,R+x]替换。

n,q<=152501

很容易在 O(n) 的时间内计算出一段区间的数字和的期望。

操作二改动极小。 我们发现多维护一些信息就可以进行区间合并,用线段树维护一 下即可。

用可持久化 Treap 维护序列就可以支持操作二。 空间限制紧需要定期重构。

T3 51nod1623

正解:dp套dp

对于一个数,最小操作数的统计可以维护一个栈,从高位到低位依次考虑每一位,设当前数字为x,将栈里所有大于x的数字删除,如果此时栈里没有数字x则加入,并且答案+1。
数位dp,用一个二进制数来表示栈里有哪些元素。
这里只考虑1~R的计算。
设数字R有n位,a[i]表示第i位。
设某数第i位的数字为x,且x<a[i],且第i+1位~第n位数字与R相同,将这个数记为(i,x),
可以通过这个标准将数分类,最多18*9种分类。
对于一种分类,统计这种分类里有几个数符合题目要求。
计算出此时栈的状态和已累加的答案(即最小操作数),记为 t1,t2 , dp[t1][i−1][K−t2] 为这类里符合要求的数的数量(K为输入要求的最小操作数)。
dp[i][j][k] 表示当前栈里的元素状态为i,再填j位数字,使答案(即最小操作数)刚好再加k的方案数,这个可以通过枚举下一位数字转移得到。

总结

……

还是好好学习吧

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值