因为前几天家里的原因有事,训练不太集中就是零碎看点东西,到后半段才开始正式训练。专题内的树状数组主要说两个一个是二维树状数组和与dp组合的优化,后面那个我印象实在是太深了,还有就是我真是写一个TLE一个后来我都不从hdu上交,先去vjudge上交过了再从hdu上交。一维树状数组很容易扩展到二维,在二维情况下:数组A[][]的树状数组定义为:
C[x][y] = ∑ a[i][j], 其中,
x-lowbit(x) + 1 <= i <= x,
y-lowbit(y) + 1 <= j <= y
与dp一起主要是LIS和LCS,可以树状数组维护g数组。原始的树状数组改造后可以支持单点修改(只增不减)和前缀最大值查询。把树状数组的加法换成取最大值,最后整个g数组的最大值就是答案。还有的题是二维树状数组和dp的组合,这一部分我没有练习。
再就是我看的计数原理,欧几里得算法,拓展欧几里得算法,素数定理和里面的一个欧拉phi函数,但是中国剩余定理那里我还没有补上。
欧几里德算法没啥说的辗转相除,拓展欧几里德就是ax+by=gcd(a,b),已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d解一定存在,这个地方解模线性方程组。素数定理x/lnx感觉那个表特别有用,就是求素数大致的范围,我不会画图没法传上来。欧拉phi函数的作用是用来求1~n中与n互素的数的个数
欧拉函数的证明
#include<cstdio>
#include<cstring>
#include<cmath>
int phi[5000000];
///考虑到若所计算的数字是6,当i=2和i=3时都将会进入内层循环,
///一旦进入内层循环就会在该素数的基础上进行欧拉公式的运算
///插入:欧拉公式:phi(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pn)
///可以想到对于每一个确定的数字n来说,其欧拉公式的运算并不在一次循环中完成,
///但可以证明的一点是,当整个循环完成时,其欧拉公式的运算会完成,换句话说,是能够保证
///phi(n)这个数组中是严格按照欧拉公式算得的正确答案,而非按照其他算法
void phi_table(int n,int* phi)
{
for(int i=2;i<=n;i++)
{
phi[i]=0;
}
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!phi[i])
{
for(int j=i;j<=n;j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j] = phi[j]/i*(i-1);
}
}
}
}
int main()
{
phi_table(10000,phi);
int n;
while(scanf("%d",&n))
printf("%d\n",phi[n]);
}
计数原理我还没有看完,光看了排列组合二项展开。先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。这部分我做的题目还比较少,下星期可能还要补线段树,找一些别人的专题和小蓝书Uva上的题稍微做一下。数学这个地方就感觉是越看越多,特别是从网上一找资料就没边了,而且这部分太看感觉了,跟前面的知识点都不太一样,特别零碎。