首页 > 编程语言 >算法基础模板整理(高阶数据结构篇)

算法基础模板整理(高阶数据结构篇)

时间:2023-04-14 13:33:57浏览次数:29  
标签:pre return int tree add 数据结构 高阶 模板 op

树状数组

动态区间和询问 + 点修改

int lowbit(int x){
    return x & -x;
}

void add(int x, int v){
    for(int i = x; i <= n; i += lowbit(i)) tree[i] += v;
}

int query(int x){
    int res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tree[i];
    return res;
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ ){
        cin >> a[i];
        add(i, a[i]);
    }
    
    while(m--){
        int k, a, b; cin >> k >> a >> b;
        if(!k) cout << query(b) - query(a - 1) << endl; //区间和询问
        else add(a, b);    //点修改
    }
}

点询问 + 区间修改

int lowbit(int x){
    return x & (-x);
}

void add(int x, int c){
    for(int i = x; i < N; i += lowbit(i)) tree[i] += c;
}

int query(int x){
    int res = a[x];
    for(int i = x; i; i -= lowbit(i)) res += tree[i];
    return res;
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ ) cin >> a[i];

    while(m -- ){
        char op; cin >> op;
        if(op == 'Q'){
            int x; cin >> x;
            cout << query(x) << endl;
        }else{
            int l, r, c; cin >> l >> r >> c;
            add(l, c), add(r + 1, -c);
        }
    }

    return 0;
}

动态区间和询问 + 区间修改

ll tree[2][N];  //tree[0][]维护bi, tree[1][]维护i*bi
ll pre[N];      //初始前缀和
ll a[N];
int n, m;

int lowbit(int x){
    return x & (-x);
}

void add(int flag, int x, int d){
    for(int i = x; i <= n; i += lowbit(i)) tree[flag][i] += (ll)d;
}

ll query(int flag, int x){
    ll res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tree[flag][i];
    return res;
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ )
        cin >> a[i], pre[i] = pre[i - 1] + a[i];

    while(m -- ){
        char op; cin >> op;
        if(op == 'Q'){
            int l, r; cin >> l >> r;
            ll res = 0;
            res += pre[r] + (r + 1) * query(0, r) - query(1, r);
            res -= pre[l - 1] + l * query(0, l - 1) - query(1, l - 1);
            cout << res << endl;
        }else{
            int l, r, d; cin >> l >> r >> d;
            add(0, l, d), add(0, r + 1, -d);
            add(1, l, l * d), add(1, r + 1, (r + 1) * (-d));
        }
    }

    return 0;
}

树状数组求逆序对

int lowbit(int x){
    return x & (-x);
}

void add(int x, int c){
    for(int i = x; i < N; i += lowbit(i)) tree[i] += c;
}

int query(int x){
    int res = 0;
    for(int i = x; i; i -= lowbit(i)) res += tree[i];
    return res;
}

int main(){
    cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> h[i], h[i] ++ ; 
//有可能存在身高为0的人 (卧槽!?)  
    for(int i = 1; i <= n; i ++ ){  //正序遍历 统计前面比h[i]高的人
        cnt[i] += query(N - 1) - query(h[i]);  //区间和为大于身高h[i]的区间内人数之和
        add(h[i], 1);    //该身高人数 + 1
    }

    memset(tree, 0, sizeof(tree));   //树状数组重新初始化 
    for(int i = n; i; i -- ){  //倒序遍历 统计后面比h[i]严格小的人
        cnt[i] += query(h[i] - 1);    //区间和为严格小于h[i]的区间内人数之和
        add(h[i], 1);    //该身高人数 + 1
}

    ll res = 0;  //累加不高兴度
    for(int i = 1; i <= n; i ++ )
        res += (ll)(1 + cnt[i]) * cnt[i] / 2;   //等差数列求和
    cout << res;

    return 0;
}


线段树

区间最值询问 + 点修改

struct node{
    int l, r, maxv;
}tree[4 * N];
typedef long long ll;
int n = 0;

void build(int u, int l, int r){
    tree[u] = {l, r};
    if(l == r) return;
    int mid = (l + r) >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}

//区间最值询问
int query(int u, int l, int r){
    if(tree[u].l >= l && tree[u].r <= r) return tree[u].maxv;
    int mid = (tree[u].l + tree[u].r) >> 1;
    int v = 0;
    if(l <= mid) v = query(u << 1, l, r);
    if(r > mid) v = max(v, query(u << 1 | 1, l, r));
    return v;
}

//点修改
void modify(int u, int x, int v){
    if(tree[u].l == tree[u].r) tree[u].maxv = v;
    else{
        int mid = (tree[u].l + tree[u].r) >> 1;
        if(x <= mid) modify(u << 1, x, v);
        else modify(u << 1 | 1, x, v);
        tree[u].maxv = max(tree[u << 1].maxv, tree[u << 1 | 1].maxv);
    }
}

标签:pre,return,int,tree,add,数据结构,高阶,模板,op
From: https://www.cnblogs.com/MAKISE004/p/17318023.html

相关文章

  • Java基础--数据结构
    数据结构Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:枚举(Enumeration)、位集合(BitSet)、向量(Vector)、栈(Stack)、字典(Dictionary)、哈希表(Hashtable)、属性(Properties)以上这些类是传统遗留的,在Java2中引入了一种新的框架-集合框架(Collection)Java......
  • 数据结构与对象------Redis
    参考《Redis设计与实现》系列文章目录和关于我一丶简单动态字符串当redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,就会使用SDS(simpledynamicstring)来表示字符串值。比如setmsg"helloworld"将创建一个新键值对,键值对的键是一个字符串对象(存储着msg),......
  • 什么是高阶函数
    原文点此跳转什么是高阶函数?有两种情况都可以被定义为高阶函数,第一种是把函数作为参数传递给另外一个函数,第二种是把函数作为另一个函数的返回结果。就像我们平时调用函数,一般都是传递值类型或者对象和数组等参数,或者是函数返回结果是值类型或者是对象和数组,高阶函数就是把上面提到......
  • Redis基础数据结构
    五种基础数据结构:string(字符串)、list(列表)、set(集合)、hash(集合)和set(有序集合)使用命令redis-cli即可连接使用go语言代码连接redis:import( "github.com/go-redis/redis")varc*redis.Clientfuncmain(){ c=redis.NewClient(&redis.Options{ Addr:......
  • 关于前端基础数据结构的问题
    常用的数据集采用数组的好处,当然对于前端新人来很容易混淆,如下的数据是数组(js的数组本就是特殊的对象,因此又叫数组对象)由于这缘故很多网上的叫法五花八门所以下面的数据结构很容易混淆,以为这是数组对象(其实这样叫没错,只是理解成是真对象(js的数组也是对象的一种,先区别一下免得混淆......
  • 【D02】Bootstrap免费精选模板推荐,附上Django中使用模板教程
    前端模板-AnchorUIKIT前言今天介绍一款制作精良、开源、免费的Bootstrap模板——AnchorUIKIT该模板使用的是Bootstrapv4版本本文将介绍如何在Django中导入该模板的静态资源包并使用介绍官方文档Anchor-afreeBootstrapUIKit(bootcss.com)预览官方文档......
  • CAD模板怎么设置?CAD模板设置技巧
    在CAD制图过程中,如果需要设置一个模板的话该如何操作呢?CAD模板怎么设置?本节CAD制图教程就和小编一起来了解一下浩辰CAD软件中设置CAD模板的相关操作技巧吧!CAD模板设置步骤:步骤一:启动浩辰CAD后,打开或者是新建一个可以作为模板的图形文件。步骤二:点击软件左上角的【G】图标,在下拉......
  • [转载]php递归生成树形结构(几种常见的数据结构)
    版权声明:本文为CSDN博主「陈文焕」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_23116221/article/details/109910846pid找上级id$array=array(array('id'=>1,'pid'=>0,'n'=>'河北省'),ar......
  • go语言基础-基本数据结构
    0x00基本数据结构go语言中,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。0x00整型(int)整型分为以下两个大类:按长度分为:int8、int16、int32、int64对应的无符号整型:uint8、uint16、uint32、uint64。其中,uint8就是我们熟知的......
  • 数据采集代码 模板化,标准化(放到dll)
     socket通信:ip,port,timeout(别忘,300),关闭连接串口通信:串口号,波特率,超时等,字符编码(别忘,),关闭连接 。overtcp(串口服务器) 指令拼接:标准化,写到dll,做好备注。 -----------------比如下面代码中,tostring使用,--------------------------vs没有提示x和X的区别,写到自己的工作dl......