zoukankan      html  css  js  c++  java
  • [模板]主席树

    主席树其实我还是不太懂,但是就是一个数据结构,维护权值线段树,每次维护一个新的根节点,查询的时候直接把两个版本查就行了.剩下的做题去领悟吧!

    poj2104

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    #define pr pair<int,int>
    #define mp make_pair
    const int INF = 1 << 30;
    const double eps = 1e-8;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int MAXN = 100010;
    struct node
    {
        int l,r,sum;
    }tree[MAXN * 20];
    int cnt = 0;
    void insert(int &num,int &x,int l,int r)
    {
        tree[cnt++] = tree[x]; x = cnt - 1;
        ++tree[x].sum;
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(num <= mid) insert(num,tree[x].l,l,mid);
        else insert(num,tree[x].r,mid + 1,r);
    }
    int query(int lst,int now,int k,int l,int r)
    {
        if(l == r) return l;
        int mid = (l + r) >> 1;
        int t = tree[tree[now].l].sum - tree[tree[lst].l].sum;
        // int mid = (r + l) >> 1;
        if(k <= t) return query(tree[lst].l,tree[now].l,k,l,mid);
        else
        return query(tree[lst].r,tree[now].r,k - t,mid + 1,r);
    }
    struct A
    {
        int x,idx;
        bool operator < (const A &rhs) const
        {
            return x < rhs.x;
        }
    };
    A a[MAXN];
    int Rank[MAXN],root[MAXN];
    int n,m;
    int main()
    {
        tree[0].l = tree[0].r = tree[0].sum = 0;
        root[0] = 0;
        while(scanf("%d%d",&n,&m) != EOF)
        {
            tree[0].l = tree[0].r = tree[0].sum = 0;
            root[0] = 0;
            duke(i,1,n)
            {
                read(a[i].x);
                a[i].idx = i;
            }
            sort(a + 1,a + n + 1);
            cnt = 1;
            duke(i,1,n)
            {
                Rank[a[i].idx] = i;
            }
            duke(i,1,n)
            {
                root[i] = root[i - 1];
                insert(Rank[i],root[i],1,n);
            }
            while(m--)
            {
                int now,lst,k;
                read(lst);read(now);read(k);
                printf("%d
    ",a[query(root[lst - 1],root[now],k,1,n)].x);
            }
        }
        return 0;
    }
  • 相关阅读:
    [C#]MagicLibrary.dll控件的使用(一)(下拉菜单)
    [SQL server]查询用户表及表结构
    [ASP.net]ASP.net的RUL重写
    [C#]简单XP菜单的实现(一)
    [Javascript]IFRAME运用(1)
    [ASP.net]未解的疑惑!
    [乱七八糟]Google搜索使用详细
    [Javascript]IFRAME运用(2)
    [随文杂记]残局
    [CSS]RevealTrans 滤镜
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10040307.html
Copyright © 2011-2022 走看看