模拟赛3 题解

爆灵力……


CF995E Number Clicker

很有意思的题。
算法一:双向广搜
据说状态数最多 \(10^7\),可过。
算法二:随机化
首先介绍一个前置理论:生日攻击
这个理论最通俗的描述是说,\(23\) 个人中有两个人生日相同的概率超过 \(50\%\)(假设一年有 \(365\) 天),\(70\) 个人时概率为 \(99.9\%\),而在人数达到 \(200\) 时,概率已经非常逼近 \(100\%\)(准确说是 \(1-2\times 10^{-29}\))。
这个理论常用于哈希碰撞攻击。形式化地,对于一个值域范围为 \(n\) 的整值函数,设其定义域范围为 \(k\) 时出现相同值的概率为 \(p\),则有

\[p=1-\overline{p}=1-\frac{n^{\underline{k}}}{n^k} \]

其中 \(n^{\underline{k}}\)\(n\)\(k\) 次下降幂。
解出这个方程可得:当 \(k>\sqrt{\frac{\pi}{2}n}\) 时,\(p>50\%\)(具体做法康这里)。
所以我们只需为 \(u,v\) 分别随机生成 \(\sqrt{p}\) 条长度为 \(100\) 的操作路径即可求解,复杂度 \(O(\sqrt{p}\log p)\)
算法三:这叫啥啊我也不知道
期望更优的方法,很神奇。
考虑为 \(u,v\) 分别生成一个到 \(0\) 的操作路径,具体方法是随机取一个整数 \(x\in [1,p-1]\),记 \(a\equiv ux\pmod p,b=x\),对 \((a,b)\) 使用更损相减术迭代至 \(b=0\)。考虑这么做的意义,由于 \(u\equiv\dfrac{a}{b}\pmod p\),那么减一操作相当于 \(\dfrac{a}{b}\to \dfrac{a-b}{b}\pmod p\),求逆操作相当于 \(\dfrac{a}{b}\to\dfrac{b}{a}\pmod p\) 太神奇了!
\(v\) 同理,由于操作可逆,所以只需将 \(v\) 的操作中所有的减换成加即可。
当然在实际实现中我们得先用辗转相除计算路径长度,如果小于 \(100\) 再用更损相减。
官方题解说这个做法“It happens to take a few steps in most cases, but we have no proof.”
(代码跑了 0ms,我惊了

#include <bits/stdc++.h>
using namespace std;
mt19937 rng(1919810);

const int N=105;
int u,v,p,s1[N],s2[N];

int gcd(int a,int b) {return b?gcd(b,a%b)+a/b+1:0;}

int solve(int n,int s[])
{
	int a,b,cnt=0;
	do b=rng()%(p-1)+1,a=1LL*b*n%p;
	while(gcd(a,b)>100);
	while(b)
		if(a<b) s[++cnt]=3,swap(a,b);
		else s[++cnt]=2,a-=b;
	return cnt;
}

int main()
{
	scanf("%d%d%d",&u,&v,&p);
	int len1=solve(u,s1),len2=solve(v,s2);
	printf("%d\n",len1+len2);
	for(int i=1;i<=len1;++i) printf("%d ",s1[i]);
	for(int i=len2;i;--i) printf("%d ",s2[i]==2?1:3);
	return 0;
}

CF300D Painting Square

这道题 CF 上 \(k<1000\),所以可以不用 NTT 水过,但毒瘤把数据加强到 \(k<50000\) 了,只能用 NTT 了 555……
还没学 NTT,先把式子放到这吧(早晚会学的,口亨~)。
先考虑一个显然的 DP,记 \(f_{i,j}\) 表示边长为 \(2^i+1\) 的正方形切 \(j\) 刀的方案数,有

\[f_{i,j}=\sum_{a+b+c+d=j-1}f_{i-1,a}f_{i-1,b}f_{i-1,c}f_{i-1,d} \]

\(g_{i,j}=\sum\limits_{a+b=j}f_{i,a}f_{i,b}\),则 \(f_{i,j}=\sum\limits_{a+b=j-1}g_{i-1,a}g_{i-1,b}\)
直接算 \(O(k^2\log n)\),NTT 优化后 \(O(k\log k\log n)\)

CF724E Goods transportation

部分分有一个显然的网络流,由于 \(n<10000\) 过不了。

猜你喜欢

转载自www.cnblogs.com/wzzyr24/p/12771267.html
今日推荐