补前两天的坑
这两天复习了yl的讲的数据结构
1.对于单调队列的学习,例题sliding window。
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
输入输出格式
输入格式:
输入一共有两行,第一行为n,k。
第二行为n个数(
#include<cstdio>
#include<iostream>
#include<functional>
using namespace std;
int head,tail,arr[1000001],qu[1000001],index[1000001],n,ans[1000001],k;
void getMins()
{
head=0;tail=1;
for(int i=1;i<k;i++)
{
while(tail>=head&&qu[tail]>=arr[i])tail--;
qu[++tail]=arr[i];
index[tail]=i;
}
for(int i=k;i<=n;i++)
{
while(tail>=head&&qu[tail]>=arr[i])tail--;
qu[++tail]=arr[i];
index[tail]=i;
while(index[head]<=i-k)head++;
ans[i-k]=qu[head];
}
}
void getMaxs()
{
int tail=0;head=1;
for(int i=1;i<=k;i++)
{
while(tail>=head&&qu[tail]<=arr[i])tail--;
qu[++tail]=arr[i];
index[tail]=i;
}
for(int i=k+1;i<=n;i++)
{
while(tail>=head&&qu[tail]<=arr[i])tail--;
qu[++tail]=arr[i];
index[tail]=i;
while(index[head]<=i-k)head++;
ans[i-k]=qu[head];
}
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)scanf("%d",&arr[i]);
getMins();
for(int i=0;i<=n-k;i++)cout<<ans[i]<<' ';
getMaxs();
cout<<endl;
for(int i=0;i<=n-k;i++)cout<<ans[i]<<' ';
cout<<endl;
return 0;
}
2.对于堆应用的学习
yl讲的手写堆各种t,于是问邹神要了左偏树的模版,最终还是觉得这个坑留着以后再填,先学会stl的堆操作和优先队列。
stl堆操作
make_heap(&a[1],&a[n+1]);
sort_heap(&a[1],&a[n+1]);
push_heap(&a[1],&a[n+1]);
pop_heap(&a[1],&a[i]);(i>=n+1)
默认为大根堆,可以添加cmp函数变为小根堆,在每个语句括号里的最后面添加。
其实是比较坑爹的,每次push或pop完都要重新make一遍
不如用优先队列。
优先队列的方法比较简单
priority_queue qu;
默认为大根堆,可以取负变为小根堆。
下面附合并果子代码,贪心+优先队列
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int n,heap[10001],k,s,l;
int main()
{
priority_queue<int>pq;
int sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&k);
pq.push(-k);
}
for(int i=1;i<n;i++)
{
s=-pq.top();
pq.pop();
s+=-pq.top();
sum+=s;
pq.pop();
pq.push(-s);
}
cout<<sum;
return 0;
}
因为纠结了一天的堆再加上买黄学长的课件及zhx说的小黄鸭等,并没有学多少东西,所以两天合在一起整理了,好困,我要去睡会。
上学晚上再熬夜玩王者荣耀剁手!!