位运算+贪心:位运算枚举第一行,2-5行可借用前一行结果得出。
三柱Hanoi : d[n] = 2d[n-1] +1 求A的B次方所有约数之和mod9901 (A<5*1e7) 分形 二维前缀和 经典差分出三种情况 差分前缀和 求最大子矩阵 O(n3) 经典连续字段和,枚举两行,转化两行间矩阵的的最大连续字段和,枚举两行n2,枚举列n,共计n3 https://www.cnblogs.com/fll/archive/2008/05/17/1201543.html 说的很好很详细 裸最大连续字段和 求数列中一段平均数最大,长度不小于L的连续字段 在日本人写的书里初见这道题好像没有长度的限制 单独拿出来先说 其实直接转化为了最大连续字段和的裸题 ,直接参照上方的 POJ1050。 2.考虑 “长度不小于L” 这个限制. 交互题:询问 1e4 次求得有向图拓扑序 n<=1e3 排序+离散化,记得离散化的时候把输入的三个数组的数都放进一个数组离散就好了,反正是一起查询。离散化可以用 sort + unique + erase 也可下面代码写法,难度是不大。 东北赛,中位数性质 动态维护中位数问题 “对顶堆” 在线做法:维护两个二叉堆,一个大根堆,一个小根堆,始终保持 类似快速排序的思想,O(n) 其实就是求逆序对数,归并排序解决。 CH 0503 奇数码问题 总而言之,n * m的数码问题的有解性判定,可以转化为归并排序求逆序对数来解决。 传送门:ACM-ICPC Beijing 2016 Genius ACM(倍增+二分) 数据范围与约定 当左端点L确定下来时,如果在L~N上二分R,其实是不合适的,因为T的值比较小,很可能R只是扩展了很短的一点点,所以需要一个与右端点R扩展长度比较匹配的算法,在这里考虑倍增。 如果排序不用快排,而采用归并排序对新增的长度部分排序,然后合并新旧两段,总复杂度可降到 O(NlogN) 贪心:奶牛排序,每只奶牛枚举一边防晒霜,找能用的防晒霜里SPF值最大的。 贪心:牛的开始时间排序,可以开一个堆,一旦没有能满足的就开新堆,多个满足的选择结束时间较早的。 贪心,坐标,区间 贪心,左右手乘积排序,可以使用微扰(邻项交换)证明 题意:有一棵树,每个节点都有一个代价基值Ci。现在要给每个点染色,第一个染根节点,其余的节点染色的时候其父节点必须已染色。每个节点染色会用掉一个时间单位,每个节点染色的代价是染完此节点时的总时间T*Ci。问染完全部节点所需要的最小代价。 试想,如果没有父节点排在节点之前的限制,那么这个题目非常简单,只需要将结点按照权值从大到小排列即可。加上了这个限制之后,如果权值最大的那个节点一旦满足了条件(父节点被排在了之前的某个位置),那么这个权值最大的节点一定要紧挨着这个父节点,即把这个权值最大的节点排在它所能排的最前面的位置。因为对于这个节点如果不受限制应该排在第一位,而有了限制,在满足了限制之后也应把它尽可能地排在前面。所以它一定是挨着父节点的。那么现在在最终的排列中我们确定了两个节点的前后相邻关系,将他们绑定在了一起。 试想如果保持这个相邻关系的同时去掉其他节点的限制,那么我们应该如何排列呢?我们假设绑定在一起的两节点是a和b。现有一个另外的节点x,我们看两种排列xab,abx对最终的计算结果有什么影响。xi+a(i+1)+b*(i+2); 将这个定理进行一下推广,绑定在一起的不一定是两个节点,可以是一个更长的序列,与这个序列进行比较看谁放在前面的也可以是一个序列。设一个序列有n1个节点,第二个序列有n2个节点。那么我们比较两者谁放在前面的时候需要比较的是(n1个权值之和×n2)和(n2个权值之和×n1)。即左移和右移产生的结果变化。当然也可以比较(n1个权值之和/n1)和(n2个权值之和/n2)。 我们可以再次进行推广,如果我们要排列的不是节点,而是许多序列的话,那么我们只需要计算每个序列权值的平均数(例如:n个节点的序列,要计算n个权值之和/n),然后按照这个平均数从大到小排列即可使得计算结果最小。这样就可以让序列与节点有了一个统一的衡量值——平均数。 这样一来,我们就可以将上面的绑定两节点的操作看成是将问题规模缩小的操作,在帮定两节点的同时我们在树中也将两节点合并,变为一个节点,即将子节点的孩子变为父节点的孩子。然后合并后的节点的权值是合并在这个节点中的所有节点的权值的平均数。我们成功的将问题规模减小了1。只需要不断这样做即可将问题缩减为只有一个节点。
四柱Hanoi : f[n] = min(2f[i]+d[n-1]) 1<=iPOJ1845 sumdiv
对A分解质因数
sum(p,c)=1+p+p^2+…+p ^c
分治求sum 分奇偶:
c为奇:sum(p,c)
= (1+p+…+p^(c-1)/2) + p ^(c+1)/2 * (1+p+…+p ^(c-1)/2)
=(1+p ^(c+1)/2) *sum(p,(c-1)/2)
c为偶:sum(p,c)
=(1+p ^(c/2)) *sum(p,c/2-1)+p ^ cPOJ3889 城市扩建:
BZOJ1218 激光炸弹
CH0304 IncDec Sequence
选择 ai 和 aj
选择 ai 和 an+1
选择 a1z 和 aj
产生 |p-q|+1 种不同的b1的值
所以序列可能就是 |p-q|+1POJ3263 Tallest Cow
POJ1050 To The Max
for(i=0;i<n-1;++i)
{
for(j=i+1;j<n;++j)
{
tmp=0;
for(k=0;k<n;++k)
{
//相当于把子矩阵多行压缩为一行了
m[i][k]+=m[j][k];
if(tmp>0)tmp+=m[i][k];
else tmp=m[i][k];
if(tmp>max)max=tmp;
}
}
}
printf("%d\n",max);
int maxSubArray(int n,int a[])
{
int b=0,sum=-10000000;
for(int i=0;i<n;i++)
{
if(b>0) b+=a[i];
else b=a[i];
if(b>sum) sum=b;
}
return sum;
}
POJ2018 Best Cow Fences
二分答案,把数列中每个数减去二分答案值,就转化为判定“是否存在一个长度不小于L的字段,字段和非负”
1.不考虑 “长度不小于L” 这个限制 O(n)
用前缀和 O(n)检验二分答案的可行性
单调性why?斜率相关,留个坑。AcWing 113 特殊排序
数学归纳法证明:k-1 有序时,插入第k个可二分,水题,总询问数 NlogNCF 670C Cinema
#include
CH 0501 货仓选址
POJ 3784 Running Median
1.序列中从小到大排名为 1~M/2 的整数存储在大根堆中
2.序列中从小到大排名为 M/2+1~M 的整数存储在小根堆中
任何时候,如果一个堆中元素个数过多,打破了这个性质,就取出该堆的对顶插入另一个堆求第k大数
POJ 2299 Ultra-QuickSort
其实可以巧妙的转化为两个状态平铺开来,转化为状态逆序对数是否相同,因为上下还是左右不改变逆序对奇偶性,必要性很好证明,充分性假装证明了。
转化为n为偶数的情况,有“逆序对数之差”和“两个局面下的空格所在行数之差”奇偶性相同。
再拓展到 n * m 的情况,根据列数奇偶性分情况讨论推到即可。
CH 0601 Genius ACM
T≤12
1≤n,m≤5e5
0≤k≤1e18
0≤Pi≤2e20
1.初始化 p=1,R=L
2.求出 [L,R+p] 这一段区间的“校验值”,若“校验值”<=T,则R+=p,p*=2,否则p/=2。
3.重复上一步操作,直到 p 的值变为0,此时 R 即为所求。
总体时间复杂度为 O(Nlog2N)POJ 3614 Sunscreen
POJ3190 Stall Reservation
POJ 1328 Radar Installation
NOIP2012/CH0701 国王游戏
POJ 2054 Color a Tree
贪心+难+好题 分析如下:
ai + b(i+1) +
x*(i+2)。后者减去前者等于2x-(a+b)。即将x从ab之前挪到ab之后,ab各左移1位,结果减小a+b。x右移2位结果增加2x。因此两者谁在前谁在后我们只需要比较a+b和2x即可,也可以比较(a+b)/2和x。//贪心:如果这棵树中有最大权值点X(非根),
//那么一旦X的父节点Y已经染色,就应该立刻染X
//于是X和Y合并成一个点集,
//新点集的权值=(新点集中所有点的权值和)/(新点集中点的个数)
//类似的,该点集可以看为一个点
//重复上述贪心思路,直到最后只剩下一个根r点集
#include