线段树 大根堆 模版二合一

#include "stdafx.h"

#include <cstdio>
#include <iostream>
#include <algorithm>

#define N 2000001

using namespace std;

inline void read_int(int &now_);

class T_heap {
private:
    int heap[N], num;

public:
    void up(int now)
    {
        if (now <= 1) return;
        if (heap[now] > heap[now >> 1])
        {
            swap(heap[now], heap[now >> 1]);
            up(now >> 1);
        }
    }

    void down(int now)
    {
        int next = now;
        if ((now << 1) <= num)
        {
            if (heap[now << 1] > heap[next])
            {
                next = now << 1;
            }
        }
        if ((now << 1 | 1) <= num)
        {
            if (heap[now << 1 | 1] > heap[next])
            {
                next = now << 1 | 1;
            }
        }
        if (now != next)
        {
            swap(heap[next], heap[now]);
            down(next);
        }
    }

    void push(int x)
    {
        heap[++num] = x;
        up(num);
    }

    void pop()
    {
        heap[1] = heap[num--];
        down(1);
    }

    int top()
    {
        return heap[1];
    }
};

class T_tree {
public:
    int l, r, dis, flag, mid;

    void mid_()
    {
        mid = (l + r) >> 1;
    }

    void dis_()
    {
        read_int(dis);
    }

    void flag_()
    {
        flag = 0;
    }
};
class T_tree tree[N * 4];

int n,if_z;

char Cget;

inline void read_int(int &now_)
{
    now_ = 0,if_z=1, Cget = getchar();
    while (Cget<‘0‘ || Cget>‘9‘)
    {
        if (Cget == ‘-‘) if_z = -1;
        Cget = getchar();
    }
    while (Cget >= ‘0‘&&Cget <= ‘9‘)
    {
        now_ = now_ * 10 + Cget - ‘0‘;
        Cget = getchar();
    }
    now_ *= if_z;
}

inline void tree_up(int now)
{
    tree[now].dis = tree[now << 1].dis + tree[now << 1 | 1].dis;
}

inline void tree_down(int now)
{
    if (tree[now].l == tree[now].r) return;
    tree[now << 1].flag += tree[now].flag;
    tree[now << 1].dis += tree[now].flag*(tree[now << 1].r - tree[now << 1].l + 1);
    tree[now << 1 | 1].flag += tree[now].flag;
    tree[now << 1 | 1].dis += tree[now].flag*(tree[now << 1 | 1].r - tree[now << 1 | 1].l + 1);
    tree[now].flag_();
}

void tree_build(int now, int l, int r)
{
    tree[now].l = l, tree[now].r = r;
    if (l == r)
    {
        tree[now].dis_();
        return;
    }
    tree[now].mid_();
    tree_build(now << 1, l, tree[now].mid);
    tree_build(now << 1 | 1, tree[now].mid + 1, r);
    tree_up(now);
}

void tree_change(int now, int l, int r, int to)
{
    if (tree[now].l == l&&tree[now].r == r)
    {
        tree[now].dis += (tree[now].r - tree[now].l + 1)*to;
        tree[now].flag += to;
        return ;
    }
    if (tree[now].flag) tree_down(now);
    if (l > tree[now].mid) tree_change(now << 1 | 1, l, r, to);
    else if (r <= tree[now].mid) tree_change(now << 1, l, r, to);
    else
    {
        tree_change(now << 1, l, tree[now].mid, to);
        tree_change(now << 1 | 1, tree[now].mid + 1, r, to);
    }
    tree_up(now);
}

int tree_query(int now, int l, int r)
{
    if (tree[now].l == l&&tree[now].r == r)
    {
        return tree[now].dis;
    }
    if (tree[now].flag) tree_down(now);
    int return_=0;
    if (l > tree[now].mid) return_ = tree_query(now << 1 | 1, l, r);
    else if (r <= tree[now].mid) return_ = tree_query(now << 1, l, r);
    else
    {
        return_ += tree_query(now << 1, l, tree[now].mid);
        return_ += tree_query(now << 1 | 1, tree[now].mid + 1, r);
    }
    tree_up(now);
    return return_;
}

int main()
{

    return 0;
}
时间: 2025-01-04 01:39:48

线段树 大根堆 模版二合一的相关文章

线段树 区间更新 模版

#include <iostream> #include"cstdio" #include"string.h" using namespace std; const int N= 100005; struct node { int left; int right; int add; int sum; } tree[N*4]; int n,m; int a[N]; void init() { memset(tree,0,sizeof(tree)); mem

线段树超级大模版

建树 void build(int o,int l,int r) //o:当前建立的节点 l:左端点 r:右端点 { if(l == r) //建立叶子信息 st[o] = a[l]; else { int m = l + ((r-l) >> 1); // m 为中间点,左儿子结点为 [l,m] ,右儿子结点为 [m+1,r]: build(o << 1,l,m); //构建左儿子结点 build((o<<1)|1,m+1,r); //构建右儿子结点 st[o] = m

线段树(二)

转自:http://blog.csdn.net/liujian20150808/article/details/51137749 1.线段树的定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 举例描述: 因此有了以上对线段树的定

【BZOJ1513】[POI2006]Tet-Tetris 3D 二维线段树

[BZOJ1513][POI2006]Tet-Tetris 3D Description Task: Tetris 3D "Tetris" 游戏的作者决定做一个新的游戏, 一个三维的版本, 在里面很多立方体落在平面板,一个立方体开始落下直到碰上一个以前落下的立方体或者落地即停止. 作者想改变一下游戏的目的使得它更大众化,在新游戏中你将知道落下的立方体信息以及位置,你的任务就是回答所有立方体落下后最高的方块的高度.所有的立方体在下落过程中都是垂直的并且不会旋转.平板左下角坐标为原点,并且

POJ 2155 Matrix 二维线段树+标记永久化?

题意:链接 方法:二维线段树+标记永久化 解析:题意是比较明朗的,算一下内存发现4000^2也是可以接受的,于是就开始yy二维线段树? 对于第一层x的线段树,每个节点开一整棵y线段树. 用个二维数组就实现了? 不过发现个问题啊,这题怎么pushdown啊,标记传不下去啊.如果给x打个标记那么怎么知道y传那段啊? 于是就学了新的东西?标记永久化. 本题是单点查询嘛,标记永久化就应该是把相应的区间直接异或,不用往下传?那查询的时候怎么办呢?只需要在查询的时候把所有路过该点的区间都异或起来就OK了.貌

POJ 2155 Matrix (二维线段树)

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18143   Accepted: 6813 Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. I

超全面的线段树:从入门到入坟

超全面的线段树:从入门到入坟 \(Pre\):其实线段树已经学了很久了,突然线段树这个数据结构比较重要吧,现在想写篇全面的总结,帮助自己复习,同时造福广大\(Oier\)(虽然线段树的思维难度并不高).本篇立志做一篇最浅显易懂,最全面的线段树讲解,采用\(lyd\)写的<算法竞赛进阶指南>上的顺序,从最基础的线段树到主席树,本篇均会涉及,并且附有一定量的习题,以后可能会持续更新,那么现在开始吧! 目录 更新日志 线段树想\(AC\)之基本原理(雾*1 线段树想偷懒之懒标记(雾*2 线段树想应用

线段树入门总结

线段树的入门级 总结   线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点.      对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度.      使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,因此有时需要离散化让空间

【BZOJ2733】永无乡[splay启发式合并or线段树合并]

题目大意:给你一些点,修改是在在两个点之间连一条无向边,查询时求某个点能走到的点中重要度第k大的点.题目中给定的是每个节点的排名,所以实际上是求第k小:题目求的是编号,不是重要度的排名.我一开始差点被这坑了. 网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 这道题似乎挺经典的(至少我看许多神犇很早就做了这道题).这道题有两种写法:并查集+(splay启发式合并or线段树合并).我写的是线段树合并,因为--splay不会打+懒得学.