ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P2617 Dynamic Rankings

2021-07-03 11:03:41  阅读:184  来源: 互联网

标签:cnt return int tr Dynamic P2617 Rankings 2n include


原题链接
考察:主席树+树状数组
实际是动态主席树的模板题,反正本蒟蒻不会(.
思路:
  主席树实际是有n个根结点的线段树,如果我们修改第i棵主席树的值,后面i~n棵树都需要修改,时间复杂度最坏是\(O(n*m)\)级别的,但是主席树求区间第k小,实际就是求前缀和,而操作又涉及单点修改,这里可以考虑树状数组,n个序列,维护n棵主席树,每棵树都代表树状数组的结点.也就是说,\(root[i]\)维护的不是\([1,i]\),而是\([i-lowbit(i)+1,i]\),每一棵主席树所依赖的上一个版本是它自己
  动态开点只需要2倍空间,最坏是\(2(n+m)\),每次树状数组操作\(log_2n\)棵树,每次新开\(log_2n\)个结点,空间开到\(O((n+m)*2+(n+m)log_2^2n)\)
  时间复杂度是\(O((n+m)log_2^2n)\)

Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010,S = 20;
int n, m,a[N],idx,root[N],X[S],Y[S],cntx,cnty;
char op[2];
vector<int> nums;
struct Node{
    int l, r, cnt;
    Node operator=(const Node& x){
	     this->l = x.l;
		 this->r = x.r;
		 this->cnt = x.cnt;
		 return *this;	
	}
} tr[N*582];
struct Query{
    int l, r, k,i,t;
    bool Q;
} query[N];
int find(int x)
{
    return lower_bound(nums.begin(), nums.end(), x) - nums.begin();
}
int build(int l,int r)
{
    int p = ++idx;
    if(l==r)
        return p;
    int mid = l + r >> 1;
    tr[p].l = build(l, mid);
    tr[p].r = build(mid + 1, r);
    tr[p].cnt = 0;
    return p;
}
int insert(int last,int l,int r,int val,int x)
{
    int p = ++idx;
    tr[p] = tr[last];
    if(l==r)
    {
        tr[p].cnt+=x;
        return p;
    }
    int mid = l + r >> 1;
    if(val<=mid)
        tr[p].l = insert(tr[last].l, l, mid, val,x);
    else
        tr[p].r = insert(tr[last].r, mid + 1, r, val,x);
    tr[p].cnt = tr[tr[p].l].cnt+tr[tr[p].r].cnt;
    return p;
}
int lowbit(int x)
{
    return x & -x;
}
void add(int k,int v)
{
	int x = find(a[k]);
    for (int i = k; i <= n;i+=lowbit(i))
        root[i] = insert(root[i], 0, nums.size()-1, x, v);
}
int ask(int l,int r,int k)
{
    if(l==r)
        return nums[l];
    int sum = 0;
    for (int i = 1; i <= cntx;i++)
        sum -= tr[tr[X[i]].l].cnt;
    for (int i = 1; i <= cnty;i++)
        sum += tr[tr[Y[i]].l].cnt;
    
    int mid = l + r >> 1;
    if(k<=sum)
    {
        for (int i = 1; i <= cntx;i++)
            X[i] = tr[X[i]].l;
        for (int i = 1; i <= cnty;i++)
            Y[i] = tr[Y[i]].l;
        return ask(l, mid, k);
    }
    else{
        for (int i = 1; i <= cntx;i++)
            X[i] = tr[X[i]].r;
        for (int i = 1; i <= cnty;i++)
            Y[i] = tr[Y[i]].r;
        return ask(mid + 1, r, k - sum);
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n;i++)
        scanf("%d", &a[i]), nums.push_back(a[i]);
    for (int i = 1; i <= m;i++)
    {
        scanf("%s", op);
        if(op[0]=='Q')
        {
            scanf("%d%d%d", &query[i].l, &query[i].r, &query[i].k);
            query[i].Q = 1;
            continue;
        }
        scanf("%d%d", &query[i].i, &query[i].t);
        nums.push_back(query[i].t);
    }
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    root[0] = build(0, nums.size() - 1);
    for(int i=1;i<=n;i++) root[i] = 1;
    for (int i = 1; i <= n;i++) add(i, 1);
    for (int i = 1; i <= m;i++)
    {
        if(query[i].Q)
        {
            cntx = 0,cnty = 0;
            for (int j = query[i].l-1; j;j-=lowbit(j))
                X[++cntx] = root[j];
            for (int j = query[i].r; j;j-=lowbit(j))
                Y[++cnty] = root[j];
            printf("%d\n", ask(0,nums.size()-1, query[i].k));
            continue;
        }
        add(query[i].i, -1);
        a[query[i].i] = query[i].t;
        add(query[i].i, 1);
    }
    return 0;
}

标签:cnt,return,int,tr,Dynamic,P2617,Rankings,2n,include
来源: https://www.cnblogs.com/newblg/p/14965784.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有