• 数据结构之树形结构


    链接:http://cdqz.openjudge.cn/ds/

    树状数组:

    描述

    给一个长为N的数列,有M次操作,每次操作是以下两种之一:

    (1)修改数列中的一个数

    (2)求数列中某位置的值

    输入第一行两个正整数N和M。
    第二行N个整数表示这个数列。
    接下来M行,每行开头是一个字符,若该字符为'M',则表示一个修改操作,接下来两个整数x和y,表示把x位置的值修改为y;若该字符为'Q',则表示一个询问操作,接下来一个整数x,表示求x位置的值。输出对每一个询问操作单独输出一行,表示答案。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 1e5+5;
    int a[maxn],b[maxn],c[maxn];
    int n,m;
    int lowbit(int x){
        return x&(-x);
    }
    void add(int a,int x){
        while(x <= n){
            c[x] += a;
            x += lowbit(x);
        }
    }
    int query(int x){
        int rt = 0;
        while(x > 0){
            rt += c[x];
            x -= lowbit(x);
        }
        return rt;
    }
    int main()
    {
    
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++){
            scanf("%d", a + i);
            b[i] = a[i] - a[i - 1];
            add(b[i], i);
        }
        while(m--){
            char opt;
            cin>>opt;
            if(opt == 'Q'){
                int x;
                scanf("%d",&x);
                printf("%d
    ",query(x));
            }
            else {
                int x,y;
                scanf("%d%d",&x,&y);
                add(y - a[x], x);
                add(a[x] - y, x + 1);
                a[x] = y;
            }
    
        }
        return 0;
    }
    View Code

    主席树

    描述

    给一个长为N的数列,有M次操作,每次操作是以下两种之一:

    (1)修改数列中的一个数

    (2)求数列中某位置在某次操作后的值

    输入第一行两个正整数N和M。
    第二行N个整数表示这个数列。
    接下来M行,每行开头是一个字符,若该字符为'M',则表示一个修改操作,接下来两个整数x和y,表示把x位置的值修改为y;若该字符为'Q',则表示一个询问操作,接下来两个整数x和y,表示求x位置在第y次操作后的值。输出对每一个询问操作单独输出一行,表示答案。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn = 1e5+5;
    int n, m, a[maxn];
    struct Node{
        int v;
        Node *ls, *rs;
    }pool[30* maxn], *root[maxn], *zero ,*tail = pool ;
    void build(){
        zero = ++tail;
        zero->ls = zero->rs = zero;
        zero->v = 0;
        root[0] = zero;
    }
    Node * newnode(int val){
        Node *nd = ++tail;//要有++tail 
        nd->v = val;
        nd->ls = nd->rs = zero;
        return nd;
    }
    #define Ls nd->ls, l, m
    #define Rs nd->rs, m+1, r
    Node * modify(int pos, int val, Node *nd, int l = 1, int r = n){
        Node *nnd = ++tail;
        if(l == r)nnd = newnode(val);
        else{
            int m = (l + r) >> 1;
            if(pos <= m){
                nnd->rs = nd->rs;
                nnd->ls = modify(pos, val, Ls);
            }
            else{
                nnd->ls = nd->ls;
                nnd->rs = modify(pos, val, Rs);
            }
        }
        return nnd;
    }
    int query(int pos, Node *nd, int l = 1, int r = n ){
        if(nd == zero)return 0;
        if(l == r)
            return nd->v;
        else {
            int m = (l + r) >> 1;
            if(pos <= m)return query(pos, Ls);
            else return query(pos, Rs);
        }
    }
    Node * print(int pos,Node * nd,int i){
        printf("%d
    ",query(pos,nd));
        return root[i-1];
    }
    int main(){ 
    
        scanf("%d%d",&n,&m);
        build();
        for(int i = 1; i <= n; i++){
            scanf("%d",a+i);
            root[0] = modify(i,a[i],root[0]);
            
        }
        
        for(int i = 1; i <= m; i++){
            char opt;
            cin>>opt;
            if(opt == 'M'){
                int pos,val;
                scanf("%d%d",&pos,&val);
                root[i] = modify(pos,val,root[i-1]);
            }
            else {
                int t,pos;
                scanf("%d%d",&pos,&t);
                root[i] = print(pos,root[t],i);
            }
        }
    
    }
    View Code

    描述

    给一个空数列,有M次操作,每次操作是以下三种之一:

    (1)在数列后加一个数

    (2)求数列中某位置的值

    (3)撤销掉最后进行的若干次操作(1和3)

    输入第一行一个正整数M。
    接下来M行,每行开头是一个字符,若该字符为'A',则表示一个加数操作,接下来一个整数x,表示在数列后加一个整数x;若该字符为'Q',则表示一个询问操作,接下来一个整数x,表示求x位置的值;若该字符为'U',则表示一个撤销操作,接下来一个整数x,表示撤销掉最后进行的若干次操作。输出对每一个询问操作单独输出一行,表示答案。

    #include<bits/stdc++.h>
    using namespace std;
    #define M 1000000007
    #define ll long long
    #define maxn 100008
    int len, n, s, L[maxn], a[maxn];
    struct Node{
        int v;
        Node *ls, *rs;
    }pool[maxn * 32], *tail = pool, *root[maxn];
    #define Ls nd->ls, l, m
    #define Rs nd->rs, m+1, r
    Node * build(int l = 1, int r = n){
        Node *nd = ++tail;
        if(l == r)nd -> v = 0;
        else {
            int m = (l + r) >> 1;
            nd -> ls = build(l, m);
            nd -> rs = build(m+1, r);
        }
        return nd;
    }
    int query(int pos, Node *nd, int l = 1, int r = n){
        if(l == r)return nd -> v;
        int m = (l + r) >> 1;
        if(pos <= m)return query(pos, Ls);
        else return query(pos, Rs);    
    }
    Node * modify(int val, int pos, Node *nd, int l = 1, int r = n){
        Node * nnd = ++tail;
        if(l == r)nnd -> v = val;
        else {
            int m = (l + r) >> 1;
            if(pos <= m){
                nnd -> rs = nd -> rs;
                nnd -> ls = modify(val, pos, Ls);
            }
            else {
                nnd -> ls = nd -> ls;
                nnd -> rs = modify(val, pos, Rs);
            }
        }
        return nnd;
    }
    Node * Query(int pos, Node * nd){    
        printf("%d
    ",query(pos, nd));
        return nd;
    }
    Node * Modify(int val, int pos, Node * nd){
        return modify(val, pos, nd);
    }
    Node * back(int t){    
        return root[t];
    }
    int main(){
        scanf("%d%d",&n);
        int cz = 0;
        root[0] = build();
        for(int i = 1; i <= n; i++){
            char opt;
            cin>>opt;
            int x;
            if(opt == 'A'){
                scanf("%d",&x);
                L[i] = L[i-1] + 1;
                root[i] = Modify(x, L[i], root[i-1]);
                a[++cz] = i;
            }
            else if(opt == 'Q'){
                scanf("%d",&x);
                L[i] = L[i-1];
                root[i] = Query(x, root[i-1]);
            }
            else {
                scanf("%d",&x);
                L[i] = L[a[cz - x]];
                root[i] = back(a[cz - x]);
                a[++cz] = i;
            }
        }
    }
    View Code
  • 相关阅读:
    1.Spring MVC详解
    servlet的九大内置对象
    Hibernate设置事务的隔离级别
    wamp下php报错session_start(): open(d:/wamp/tmpsess_ku776hvb06ko4lv9d11e7mnfj1, O_RDWR) failed: No such file or directory
    json_decode()相关报错
    wamp下var_dump()相关问题
    es6箭头函数内部判断
    Json数组对象取值
    npm指向淘宝源
    APICloud之封装webApp
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8723473.html
Copyright © 2020-2023  润新知