数据结构模板

队列

优先队列

方法:

和队列操作基本相同:
top 访问队头元素  // 不同点
pop 弹出队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列

默认类型:

priority_queue<int> que;  // 默认大顶推, 即从大到小 
priority_queue<int, vector<int>, greater<int> > que1; // 小顶堆 
priority_queue<int, vector<int>, less<int> > que2;  // 大顶堆 

自定义类型:

//方法1 运算符重载 <
struct node{
    int x, y;
    bool operator < (const node& a) const{
        return x < a.x; //大顶堆
    }
};
priority_queue<node> que3;

两个变量时可以直接使用pair<>;
pair排序时是先根据first,再根据second。

typedef pair<int, int> PII;
priority_queue<PII, vector<PII>, greater<PII> > heap; // 定义一个小根堆
双端队列
// 构造函数
deque<int> deq
// 增加函数
deq.push_front(x)//双端队列头部增加一个元素X
deq.push_back(x) //双端队列尾部增加一个元素x
// 删除函数
deq.pop_front()  //删除双端队列中最前一个元素
deq.pop_back()   // 删除双端队列中最后一个元素
deq.front();          //返回队头元素
deq.back();          //  返回队尾元素
deq.clear()      //清空双端队列中元素
//判断函数
deq.empty()      //向量是否为空,若true,则向量中无元素
//大小函数
deq.size()       //返回向量中元素的个数

线段树

区间修改,查询l,r区间是否为从小到大顺序。

false按顺序, true不按顺序。

struct NO {
    int l;
    int r;
    int maxn;
    int mini;
    bool flag;
};
struct SigmentT {
    NO t[N * 4];
 
    void Pushup(int p) {
        t[p].flag = t[p << 1].flag | t[p << 1 | 1].flag;
        t[p].maxn = t[p << 1 | 1].maxn;
        t[p].mini = t[p << 1].mini;
        if(t[p << 1 | 1].mini < t[p << 1].maxn) t[p].flag = 1;
    }
 
    void Build(int p , int l , int r) {
        t[p].l = l; t[p].r = r;
        if(l == r) {t[p].maxn = t[p].mini = a[l];return;}
        int mid = (l + r) >> 1;
        Build(p << 1 , l , mid); Build(p << 1 | 1, mid + 1 , r);
        Pushup(p); return;
    }
 	// p:根节点, l:左边界, r:右边界, d:要修改的值
    void Updata(int p , int l , int r , int d) {
        if(l <= t[p].l && r >= t[p].r) {
            t[p].maxn = t[p].mini = d;
            return;
        }
        int mid = (t[p].l + t[p].r) >> 1;
        if(l <= mid) Updata(p << 1 , l , r , d);
        if(r > mid) Updata(p << 1 | 1 , l , r , d);
        Pushup(p);
    }
 
 // p:根节点, l:左区间, r:右区间
    bool Query(int p , int l , int r) {
        if(l <= t[p].l && r >= t[p].r) return t[p].flag;
        int mid = (t[p].l + t[p].r) >> 1;
        bool ans = 0;
        if(l <= mid) ans |= Query(p << 1 , l , r);
        if(r > mid) ans |= Query(p << 1 | 1 , l , r);
        if(l <= mid && r > mid && t[p << 1 | 1].mini < t[p << 1].maxn && !ans) ans |= 1;
        return ans;
    }
}tr;
int main() {
    //freopen("aa.in","r",stdin);
    scanf("%d%d",&n,&q);
    for(int i = 1; i <= n; i++)
        scanf("%d",&a[i]);
    tr.Build(1 , 1 , n);
    for(int i = 1; i <= q; i++) {
        int op,x,y; scanf("%d%d%d",&op,&x,&y);
        if(op == 1) tr.Updata(1 , x , x , y);
        else if(tr.Query(1 , x , y)) printf("No\n");
        else printf("Yes\n");
    }
}
区间修改,求区间最大值和区间最大值的数目

https://ac.nowcoder.com/acm/contest/9667/B

#define  mm(a,x) memset(a,x,sizeof a)
#define  mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)

const int N = 2e5 + 10;

int n,m;
int a[N];

struct Node{
    int l,r;
    int v,cnt;
}tr[N * 4];

int maxv,cnt;

void pushup(int u){
    tr[u].v = max(tr[u << 1].v,tr[u << 1 | 1].v);
    tr[u].cnt = 0;
    if(tr[u].v == tr[u << 1].v) tr[u].cnt += tr[u << 1].cnt;
    if(tr[u].v == tr[u << 1 | 1].v) tr[u].cnt += tr[u << 1 | 1].cnt;
}

void build(int u,int l,int r){
    if(l == r) tr[u] = {l,r,a[l],1};
    else{
        tr[u] = {l,r};
        int mid = l + r >> 1;
        build(u << 1,l,mid);
        build(u << 1 | 1,mid + 1,r);
        pushup(u);
    }
}

void query(int u,int l,int r){
    if(tr[u].l >= l && tr[u].r <= r){
        if(maxv == tr[u].v) cnt += tr[u].cnt;
        if(maxv < tr[u].v){
            maxv = tr[u].v;
            cnt = tr[u].cnt;
        }
        return ;
    }
    int mid = (tr[u].l + tr[u].r) >> 1;
    if(l <= mid) query(u << 1,l,r);
    if(r > mid) query(u << 1 | 1,l,r);
}

void modify(int u,int x,int v){
    if(tr[u].l == x && tr[u].r == x){
        tr[u].cnt = 1;
        tr[u].v = v;
    }
    else{
        int mid = (tr[u].l + tr[u].r) >> 1;
        if(x <= mid) modify(u << 1,x,v);
        else modify(u << 1 | 1,x,v);
        pushup(u);
    }
}

int main() {
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ ) cin >> a[i];
    build(1,1,n);
    string op;
    int x,y;
    while(m -- ){
        cin >> op;
        scanf("%d%d",&x,&y);
        if(op == "Ask"){
            maxv = 0,cnt = 0;
            query(1,x,y);
            cout<<maxv<<" "<<cnt<<endl;
        }else{
            modify(1,x,y);
        }    
    }    
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值