基础算法
评测机一秒约能跑2e8次运算,要控制程序运算规模在1e8内(时间复杂度)
数组大小限制为128mb时,int数组空间大小为[3e7]
时间复杂度和空间复杂度均以最差估计
递归一般不超过1e6层
前缀和
一维前缀和:prefix[i]=prefix[i-1]+a[i]
二维前缀和:prefix[i][j]=a[i][j]+prefix[i-1][j]+prefix[i][j-1]-prefix[i-1][j-1]
类型:降低时间复杂度算法
核心:数组通过对前项的累加,构建出一个前缀和数组,
在前缀和数组中(结束-开始)即可得到数组在此段的和,避免多次重复计算;
四元组(题)->难点:出现了6个需要满足的不等式
->存在问题
--多不等式用栈依次解决处理,前方数满足条件就在该位置出栈
差分
一维差分:diff[i]=a[i]-a[i-1];
二维差分:diff[i][j]=a[i][j]-a[i-1][j]-a[i][j-1]+a[i-1][j-1];
二维前缀和恢复差分:a[i][j]=-a[i-1][j-1]+a[i-1][j]+a[i][j-1]+diff[i][j];
类型:降低时间复杂度算法
核心:数组的每项减去前一项,构建出一个差分数组,相当于前缀和的逆运算
差分可以使对区间的快速修改(运算后进行前缀和运算)
离散化
int getidex(int x)
{
return lower_bound(L.begin(),L.end(),x)-l.begin();//L为储存原始数据的容器
}
类型:降低时空复杂度的算法(针对大规模相差比较大的数)
核心:数值与下标的映射,使用方法暂且不明(现在有了解但我不会捏)
双指针l,r
类型:解题模型
对撞指针:两个指针相向,按照一定条件运行,相撞或错开(即l>=r)时停止
核心:视情况定
快慢指针:两个指针同向,按照一定条件运行,一快一慢,不一定是速度不同,还可以是一个动一个不动比较(某种程度上选择排序也是快慢指针)
核心:视情况定
例:美丽的区间(蓝桥1372)求多重区间
for(int i=1;i<=n;i++)
{
while(i<j||(j+1<=n && sum<S))sum+=a[++j];//此处i为左指针,j为右指针,每次i恒定对j进行扫描
if(sum >= S)ans =min(ans,j-i+1);
sum-=a[i];
}
贪心
类型:解题模型
核心:通过局部最优逐步推出全局最优
二分
类型:搜索算法
核心:通过类似二进制的转化来快速找到某个需要的值
整数二分
int l=0,r=maxn;
while(l+1!=r)
{
int mid =(l+r)/2;
if(a[mid]>=x)r=mid;
else l=mid;
}
cout<<l<<' '<<r;
-----不知道设置啥封面,封面是摄影作业。。。------