博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZOJ - 2112 Dynamic Rankings(BIT套主席树)
阅读量:6637 次
发布时间:2019-06-25

本文共 3017 字,大约阅读时间需要 10 分钟。

纠结了好久的一道题,以前是用线段树套平衡树二分做的,感觉时间复杂度和分块差不多了。。。

终于用BIT套函数式线段树了过了,120ms就是快,此题主要是卡内存。

假设离散后有ns个不同的值,递归层数是log2(ns)左右,nlog(ns),主席树是前缀区间,BIT保存修改的值是mlog2(ns)log2(ns)。

虽然这个算出来还是会爆,但是实际上会有一些结点复用,具体设置多少请相信玄学。(2e6左右)

ZOJ的Node*计算内存似乎有问题,必须用int

 

/**********************************************************            ------------------                          **   author AbyssFish                                     ***********************************************************/#include
#include
#include
#include
#include
#include
using namespace std;//#pragma pack(4)const int MAX_N = 5e4+3;const int MAX_M = 1e4+3;const int MAX_NM = MAX_N+MAX_M;const int MAX_D = 16;const int MAX_ND = 0xac*MAX_M+0x42fed;//MAX_D*MAX_N+MAX_M*MAX_D*MAX_D;int b[MAX_NM];int mp_a[MAX_NM];int ns, n_;int N, M;struct Cmd{ int i, j, k;}qus[MAX_M];struct Node{ int lc, rc; int s;}p[MAX_ND];int root[MAX_N];int cnt;#define lsn p[o].lc,l,md#define rsn p[o].rc,md+1,rvoid build(int x,int &o,int l = 1, int r = ns){ p[++cnt] = p[o]; o = cnt; p[o].s++; if(r > l){ int md = (l+r)>>1; if(x <= md) build(x,lsn); else build(x,rsn); }}int BIT[MAX_N];void inst(int x, int d, int &o, int l = 1, int r = ns){ if(o == 0){ p[++cnt] = p[o]; o = cnt; } p[o].s += d; if(l < r){ int md = (l+r)>>1; if(x<=md) inst(x,d,lsn); else inst(x,d,rsn); }}#define lowbit(x) ((x)&(-x))void modify_bit(int pos, int x, int d){ while(pos <= N){ inst(x,d,BIT[pos]); pos += lowbit(pos); }}typedef vector
Prefix;void prefix_bit(int pos, Prefix &res){ res.clear(); while(pos > 0){ res.push_back(BIT[pos]); pos -= lowbit(pos); }}inline int cal_lft(Prefix &pfx){ int re = 0; for(int i = pfx.size()-1; i >= 0; i--){ re += p[p[pfx[i]].lc].s; } return re;}#define dump(pfx,ch)\for(i = pfx.size()-1; i >= 0; i--){\ pfx[i] = p[pfx[i]].ch;\}Prefix X, Y;int qkth(int k,int l = 1, int r = ns){ if(l == r) return mp_a[l]; else { int l_cnt = cal_lft(Y)-cal_lft(X); int md = (l+r)>>1, i; if(k <= l_cnt){ dump(X,lc) dump(Y,lc) return qkth(k,l,md); } else { dump(X,rc) dump(Y,rc) return qkth(k-l_cnt,md+1,r); } }}void solve(){ cnt = 0; memset(BIT+1,0,sizeof(int)*N); int i; for(i = 1; i <= N; i++){ root[i] = root[i-1]; build(b[i], root[i]); } for(i = 0; i < M; i++){ if(qus[i].j < 0){ int pos = qus[i].i; modify_bit(pos,b[pos],-1); modify_bit(pos,b[pos] = b[qus[i].k],1); } else { int L = qus[i].i-1, R = qus[i].j; prefix_bit(L,X); prefix_bit(R,Y); X.push_back(root[L]); Y.push_back(root[R]); printf("%d\n",qkth(qus[i].k)); } }}int * const a = (int *)(p+2);int * const r = a + MAX_NM;void init(){ scanf("%d%d",&N,&M); for(int i = 1; i <= N; i++){ scanf("%d",a+i); r[i] = i; } n_ = N; char ch[3]; for(int i = 0; i < M; i++){ scanf("%s",ch); if(*ch == 'Q') { scanf("%d%d%d",&qus[i].i,&qus[i].j,&qus[i].k); } else { qus[i].k = ++n_; r[n_] = n_; scanf("%d%d",&qus[i].i,a+n_); qus[i].j = -1; } } sort(r+1,r+n_+1,[](int i,int j){ return a[i]

 

转载于:https://www.cnblogs.com/jerryRey/p/5008876.html

你可能感兴趣的文章
MODIS数据的简介和下载(四)——HTTPS服务下载说明
查看>>
Python 循序渐进教程系列 之基础02 基础数据类型
查看>>
Solr客户端自定义开发
查看>>
maven 工程 配置log4j
查看>>
mangodb的安装
查看>>
我的友情链接
查看>>
Android开发之使用pull解析XML文件
查看>>
[CentOS7] - CentOS7 连接WIFI
查看>>
cocos2dx中.json和.plist以及.xml文件格式生成加载的不同
查看>>
Dos命令查看端口占用及关闭进程
查看>>
刀片之家礼品兑换帮助
查看>>
登陆脚本实现域用户自动创建共享盘和关联打印机
查看>>
Linq in action
查看>>
Zatree2.2安装
查看>>
blockchain.info API中文手册
查看>>
Centos 7.3搭建git服务器
查看>>
下载的实现
查看>>
LVS配置文件详解及相关技巧介绍
查看>>
Windows 8 远程桌面连接 另一个Windowd 8 提示“您的凭据不工作”
查看>>
织梦DEDECMS修改摘要、标题等字数限制
查看>>