记录

  1. 在加倍数据(比如把一个数组复制两倍,或者题目给了n,实际有2n数据)时,注意数组大小有没有开对,即使是tle也可能是数组开小了。
  2. 数据范围给的边界数据都可以拿来测一下。
  3. 看看有没有地方爆了int
  4. 逆序对是可以局部求解的,可以分开考虑两两之间的贡献。
  5. 数论分块:在[l,n/(n/l)]内的i,n/i的值都相等,并且n%i是等差数列,公差为(n/l)。
  6. 一些离散数据相关的题里,在清空数据或用离散的值统计答案时,注意有没有新的值产生。
    https://codeforces.com/contest/1471/problem/D这题里,1可能是原来没有,而过程中产生的。
  7. 找中位数可以用二分,二分一个w,大于等于w的记为1,其余记为-1,只要区间和大于等于0,就是满足的。
    因为中位数一定是原本的数,所以离散化后中位数只可能取1---n。
树状数组上倍增找第k个1要先找第k个1左边位置,然后加1.
int BS(int k)
{
	k--;
	int p=0;
	for(int i=20;i>=0;i--)
		if((1<<i)+p<=N&&sum[(1<<i)+p]<=k)
			k-=sum[(1<<i)+p],p+=(1<<i);
	return p+1;
}
  1. 历史版本(可持久化数据结构)有离线的一个思路:把每个版本看成节点,版本迁移看成边,然后用数据结构维护遍历和回溯的过程。
  2. multiset和set的iterator可以用++,- -来移动。( 有时候可以用来代替平衡树)
  3. double被卡精度时可以开long double(用 %Lf 读入)
  4. 边权转成点权:可以用一个点把边分成两段,然后这个点就代表了这条边。
  5. 能合并的东西(如求和,最大值,线性基等)可以考虑用倍增优化(预处理出 i 往前 2^p这一段的值)
  6. 求树上一段链的信息,除了类似倍增lca一样,也可以模仿st表的思路,把链划成两段(要找上面一段的起点可以类似倍增lca往上走),这么做的好处是在合并复杂度较大的时候,可以把一个log的复杂度转移掉。
  7. 最小割的可行边与必须边。求一组最小割的方案:现在原图跑最大流,然后把满流边边权改为1,其余改为无穷,再跑一次最大流,这时被割的边就是一组方案。
  8. 枚举阶乘方案时可以用next_permutation
next_permutation(vec.begin(),vec.end());//得到下一个排列。
  1. 网格图在相邻格子之间任意连边得到得是一个二分图,无奇环。在网格图上的构造,或者从网格图上抽象出来建的图里经常用到。
  2. 对于一些问题边界的估计,常量不能忽略,最好写个简单的程序来计算边界。
  3. 一道题卡20分钟就可以换了。看过题人数,不要作死上鬼畜做法。
  4. 解线性同余方程
p = a[1]*x[1]+w[1]
p = a[2]*x[2]+w[2]

换成a[1]*x[1]-a[2]*x[2]=w[2]-w[1]
用exgcd做
  1. exgcd 解 ax+by=c得到的结果(x[0],y[0])是方程ax+by=gcd(a,b)的解,换算成原方程的解是(x[0]c/gcd(a,b),y[0]c/gcd(a,b))
  2. f[i]g[n-i]的求和直接卷积。f[i]g[j+i]的求和可以令G[n-i]=g[i]后,转换成f[i]G[(n-j)-i]后卷积求和。
  3. 在模p意义下,存在一个i:[1,p-1]到j:[0,p-2]的一一映射关系,(设g为p的原根)映射关系是g^j=i(mod p) .用这个映射可以把 H[i]G[j] (i*j=C)变换成卷积的形式。
posted @ 2021-03-15 08:40  w_57  阅读(10)  评论(0编辑  收藏  举报