CodeChef - PRIMEDST

Prime Distance On Tree 题意 Prime Distance On Tree 给个树,从树上随机选取一对点$u,v$,求$\delta(u,v)$是素数的概率 Solution 可以从生成函数的角度考虑 假设rt是一个树的树根,而且rt的深度是d,将树中节点的深度统计出来,记为$f_{rt,d}$,如果$u,v…$是rt的子节点,那么rt对答案的贡献就是生成函数中素数项的系数,那么问题就是怎么计算生成函数了 $$ \sum_{u,v \in son(rt)} f_{u,1} * f_{v, 1} $$ 这个式子中的素数项系数和与下式是相等的,计算$f$是很简单的 $$ \Big(f_{rt,0}^2 - \sum_{u \in son(rt) }f_{u,1}^2\Big) / 2 $$ 为了确保复杂度不会太高,需要用点分治 #include <cstdio> #include <stack> #include <set> #include <cmath> #include <map> #include <time.h> #include <vector> #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <memory.h> #include <cstdlib> #include <queue> #include <iomanip> // #include <unordered_map> #define P pair<int, int> #define LL long long #define LD long double #define PLL pair<LL, LL> #define mset(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for (int i = a; i < b; i++) #define PI acos(-1....

📝 March 1, 2020&nbsp;·&nbsp;⌛ 4 min

Rock Paper Scissors Lizard Spock

Rock Paper Scissors Lizard Spock 题意: Rock Paper Scissors Lizard Spock 有五种手势,类似于石头剪刀布,有两个串$s, t$,由这五种手势组成,从某个位置开始匹配,如果$t_i$能赢$s_j$得一分,求一个$pos(0\le pos \le len(s)-len(t))$,使得得分最多 Solution: 将上图记为$G$,如果$op_1$可以赢$op_2$,则$G(op_1, op_2)=1$, 枚举可以得分的手势,假设当前手势为$op$, $$ \begin{aligned} t’_i &=(reverse\ t_i == op ? 1 : 0) \newline s’_i &= G[op][s_i] \end{aligned} $$ 将$t’,s’$做卷积,累加每次的结果,再遍历一遍匹配的起始位置,取最大值 #include <cstdio> #include <stack> #include <set> #include <cmath> #include <map> #include <time.h> #include <vector> #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <memory.h> #include <cstdlib> #include <queue> #include <iomanip> #include <unordered_map> #define P pair<int, int> #define LL long long #define LD long double #define PLL pair<LL, LL> #define mset(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for (int i = a; i < b; i++) #define PI acos(-1....

📝 February 11, 2020&nbsp;·&nbsp;⌛ 3 min

URAL - 1996

URAL - 1996 题意: URAL - 1996 给两个长度分别为$n, m$的字节串$A,B$,$A$串的最后一位可以修改,代价为$1$,求使得$B$串为$A$串字串的最小代价 Solution : 因为$A$串只有最后最后一位可以修改,所以可以用KMP求出可能匹配的位置,然后计算每个位置的$cost$ 记$A$串最后一位构成的串为$a$, $B$串的为$b$, 假设$pos(0\le pos \le n-m)是可能匹配的位置$,如果将$b$反转得到$b’$, 在此处的的代价为 $$ \sum_{i+j=pos+m-1} [a_i \ne b’_j ] $$ 而 $$ \sum_{i+j=posm-1} a_j * b’_j $$ 可以算出来相等的$1$的个数$cnt_1$,再将$a,b$串取反,再做一次卷积就可以算出$0$相等的个数$cnt_2$,$ans=m-cnt_1-cnt_2$ #include <cstdio> #include <stack> #include <set> #include <cmath> #include <map> #include <time.h> #include <vector> #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <memory.h> #include <cstdlib> #include <queue> #include <iomanip> #include <unordered_map> #define P pair<int, int> #define LL long long #define LD long double #define PLL pair<LL, LL> #define mset(a, b) memset(a, b, sizeof(a)) #define rep(i, a, b) for (int i = a; i < b; i++) #define PI acos(-1....

📝 February 11, 2020&nbsp;·&nbsp;⌛ 4 min