2019 CCF夏令营 day 1
来这里第一天表示非常的懵逼。然后发觉ckw讲的线性数据结构非常的难。
关于栈和队列
1.双端队列的用法
deque <int> de;
de.push_back(x);
de.push_front(x);
de.pop()_back;
de.pop()_front;
de.back();
de.front();
de.empty();
2.关于括号序列的题
这个题告诉我们考虑好||和&&的重要性。
用栈存储右括号,遇左括号则出栈判断。
#include <iostream> #include <cstdio> #include <stack> using namespace std; string s1; int len,xu; bool vis[109]; stack < pair<char,int> > q; char now; int main(){ cin>>s1; len=s1.size(); for(int i=0;i<len;i++){ if(s1[i]=='('||s1[i]=='[') q.push(make_pair(s1[i],i)); else{ if(!q.empty()){ now=q.top().first; xu=q.top().second; } if(s1[i]==')'&&now=='('){ vis[i]=1;vis[xu]=1;q.pop(); } if(s1[i]==']'&&now=='['){ vis[i]=1;vis[xu]=1;q.pop(); } } } for(int i=0;i<len;i++){ if(vis[i]==0){ if(s1[i]=='('||s1[i]==')'){ printf("()"); } if(s1[i]=='['||s1[i]==']'){ printf("[]"); } } else printf("%c",s1[i]); } return 0; }
3.单调栈
考虑这样一个问题:给你一列数字,对每个数字求出其右边第一个值大
于等于它的数字的位置。要求做到线性。
从右到左扫描整个序列,不能确定的则入栈,遇到比栈顶大的就一直出栈。直至不能再判断。(求最小时反向扫描)
4.一个题
有一列n个数字a[1]…a[n],对所有1<=L<=R<=n求
max(a[L],a[L+1],…,a[R])并求和,n<=1e6。
反向考虑,考虑一个数字最大能成为哪些区间的最大值。求出左面和右面比他大的数(反着扫一遍即可)(认为a[0]和a[n+1]是正无穷即可避免一些特判)一个小坑是遇见相等的数字时要钦定左面比右面大(例 1111111)
5.另一个题
考虑有一列n个数字,求1<=L<=R<=n使得(R-L+1)*min(a[L],a[L+1],…,a[R])最大。n<=1000000
和上一个题一样的,求出来,比较,解法非常暴力。6.还有一个题
有一个矩阵,每个位置是0或者1。求最大的全1子矩阵。n*m<=1000000。
可以用前缀和来做,也可以扫描每一行,在每一行上向上求可达的 最小值。都是o(nm)。
单调队列
题曰滑动窗口,意思就是,比你小又比你厉害的会比你出场晚。
问题是有一列数{a_n}和m个区间[L(i),R(i)],满足L(i)<=L(i+1),R(i)<=R(i+1)。对每个区间求区间最大值。
比队列头头大的,把队列排空再入队;小的直接入队。o(n)
链表
没什么用。
前缀和差分
o(n)预处理,o(1)询问
一维前缀和和二维前缀和。呃呃二维的比较难理解,
求:b[x,y]=b[x-1,y]+b[x,y-1]-b[x-1,y-1]+a[x,y]
矩阵求和:s(x1,y1,x2,y2)=b[x1-1,y1-1]+b[x2,y2]-b[x1-1,y2]+b[x2,y1-1]
二维差分非常的神奇
其实差分是前缀和的逆过程,可以由前缀和推过来。
基数排序
32768=2的15次方
基数排序是一种桶排,比较普遍的是将数字的每一位拆开来,先按照末位排,在依次由低向高推进。或由高向低推进。也可以转换为二进制来桶排。
STL
#include <algorithm>
stack,queue,deque,priority_queue,vector,set,map
deque常数不小,不要用
priority_queue是大根堆,小根堆可以插相反数或重载运算符。
vector 不要对v.size()-1!因为这是一个unsigned int型的,对空的vector-1会得到一个INF
关于v.resize()其复杂度是O(max(1, resize()中的参数-原来的size()))的
v.clear()和vector<>().swap(v)的区别。
• 前者是假装清空了,实际内存没有被回收。
• 后者是真的回收了,不过需要和v.size()的大小成正比的时间