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;
}
View Code

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()的大小成正比的时间

猜你喜欢

转载自www.cnblogs.com/jindui/p/11272543.html