青岛之行前的准备(数论为主)

青岛赛训练

0-Fantasy of a Summation

时间:10月5号23点30

https://cn.vjudge.net/contest/258301#problem
这个题,题意给出是一个k重循环,每个循环i重1到n,循环体为 res = ( res + A[i1] + A[i2] + ... + A[iK] ) % MOD;最后res的值。

分析:组合数学+快速幂

解法:

对于每个A[i]都是一样的,
所以我们算出来总的A[i]出现的次数/n就可以知道每一个出现的次数
总的次数是(nk)*k,所以每个出现(n(k-1))k
所以答案是Sum
(n^(k-1))*k%mod,最后用快速幂求解。

1-Pairs Forming LCM

时间:10月六号10:30

http://https://cn.vjudge.net/contest/258301#problem/B

分析:素数线性筛+唯一分解定律

解法:

给你一个数n  求满足lcm(a, b) == n, a <= b 的 (a,b) 的个数
容易知道 n 是a, b的所有素因子取在a, b中较大指数的积
先将n分解为素数指数积的形式
 n=p1e1*p2e2...pk^ek;
 a=p1a1*p2a2pk^ak
 b=p1b1*p2b2pk^bk
对于a,b它们的最小公倍数为n,则a1<=e1,b1<=e1那么对于每个素因子pi的个数ei在a,b中的指数ai, bi 至少有一个等于ei, 另一个小于等于ei
先不考虑a, b的大小  对于每个素因子pi:

  1. 在a中的指数 ai == ei   那么 pi 在 b 中的指数可取 [0, ei] 中的所有数  有 ei + 1 种情况
  2. 在a中的指数 ai < ei  即 ai 在 [0, ei) 中   那么 pi 在 b 中的指数只能取 ei  有 ei 种情况
    那么对与每个素因子都有 2ei + 1种情况  也就是满足条件的 (a, b) 有 π(2ei + 1)个  考虑大小时 除了 (n, n) 所有的情况都出现了两次  那么满足a<=b的有 (π(2*ei + 1)) / 2 + 1  个。

2-Incredible Chess

时间:10月六号22:30

http://https://cn.vjudge.net/contest/258301#problem/D

分析:博弈问题 nim游戏(这个游戏还没有系统的学习)

http://https://www.cnblogs.com/exponent/articles/2141477.html

解法:把每一列的棋子间隔(可以走的)看成Nim博弈中的石子数量,那么答案就所有差的异或...

3-Mergeable Stack

时间:10月七号9:00

http://https://vjudge.net/contest/258671#problem/D

分析:数据结构+模拟

解法:

题意 : 给你 1 2 3 个数,让你模拟栈的操作

1)将一个元素push到栈里;

2)将一个栈的栈顶元素输出;

3) 将两个栈合并;
模拟栈,如果用栈来操作,因为栈数目过多,爆内存
如果用vector也会爆
list容器就是一个双向链表,可以高效地进行插入删除元素,合并链表
输入输出用scanf printf
另外注意清空操作

for (int i = 1; i <= n; i++)//清空操作很必要
			List[i].clear();//n个链表

模拟三个操作

if (op == 1) {
				scanf("%d%d", &s, &v);
				List[s].push_back(v);
			}
			else if (op == 2) {
				scanf("%d", &s);
				if (!List[s].empty()) {
					printf("%d
", List[s].back());
					List[s].pop_back();
				}
				else printf("EMPTY
");
			}
			else if (op == 3)
			{
				scanf("%d%d", &s, &t);
				//c1.splice(c1.beg,c2)      将c2连接在c1的beg位置,释放c2
				List[s].splice(List[s].end(), List[t]);
			}
		}

4-Travel along the Line

时间:10月七号16:00

http://https://vjudge.net/contest/258671#problem/E

分析:组合数学+逆元+组合数模板

解法:对于这个题,题目思路弄了大半天(那真是大半天),不是说题目意思,而是最后的逆元的步骤,最后发现分子乘以分母对MOD的逆元最后取模就AC了。。。

快速幂板子
ll quick_pow(ll a, ll b, int mod)//二进制写法
{
	ll  r = 1, base = a;
	while (b)
	{
		if (b & 1)
			r = (r*base) % mod;
		base = (base*base) % mod;
		b >>= 1;
	}
	return r;
}
组合数板子
ll C(ll n, ll m) {
   if (m > n)
	       return 0;
   if (n == m)return 1;
    ll ans = 1;
	    for (int i = 1; i <= m; i++)
      ans = ans * (n - i + 1) % MOD * quick_pow(i, MOD - 2,MOD) % MOD;
	     return ans;
	
}
逆元直接用费马小定律,inv=quick_pow(a,MOD-2,MOD);
不疯魔不成活
原文地址:https://www.cnblogs.com/gzr2018/p/9746391.html