当前位置: 首页 > news >正文

P6136 【模板】普通平衡树(数据加强版)(替罪羊树模板)

测试链接

题目背景

本题是 P3369 数据加强版,扩大数据范围并增加了强制在线

题目的输入、输出和原题略有不同,但需要支持的操作相同。

题目描述

您需要动态地维护一个可重集合 MMM,并且提供以下操作:

  1. MMM 中插入一个数 xxx
  2. MMM 中删除一个数 xxx(若有多个相同的数,应只删除一个)。
  3. 查询 MMM 中有多少个数比 xxx 小,并且将得到的答案加一。
  4. 查询如果将 MMM 从小到大排列后,排名位于第 xxx 位的数。
  5. 查询 MMMxxx 的前驱(前驱定义为小于 xxx,且最大的数)。
  6. 查询 MMMxxx 的后继(后继定义为大于 xxx,且最小的数)。

本题强制在线,保证所有操作合法(操作 222 保证存在至少一个 xxx,操作 4,5,64,5,64,5,6 保证存在答案)。

输入格式

第一行两个正整数 n,mn,mn,m,表示初始数的个数和操作的个数。

第二行 nnn 个整数 a1,a2,a3,…,ana_1,a_2,a_3,\ldots,a_na1,a2,a3,,an,表示初始的数

接下来 mmm 行,每行有两个整数 opt\text{opt}optx′x'xopt\text{opt}opt 表示操作的序号($ 1 \leq \text{opt} \leq 6 ),),),x’$ 表示加密后的操作数。

我们记 last\text{last}last 表示上一次 3,4,5,63,4,5,63,4,5,6 操作的答案,则每次操作的 x′x'x 都要异或last\text{last}last 才是真实的 xxx。初始 last\text{last}last000

输出格式

输出一行一个整数,表示所有 3,4,5,63,4,5,63,4,5,6 操作的答案的异或和

输入输出样例 #1

输入 #1

6 7
1 1 4 5 1 4
2 1
1 9
4 1
5 8
3 13
6 7
1 4

输出 #1

6

说明/提示

样例解释

样例加密前为:

6 7
1 1 4 5 1 4
2 1
1 9
4 1
5 9
3 8
6 1
1 0

::::info[每一个操作的输出]
执行第一个操作前,M={1,1,1,4,4,5}M=\{1,1,1,4,4,5\}M={1,1,1,4,4,5},完成后 M={1,1,4,4,5}M=\{1,1,4,4,5\}M={1,1,4,4,5}

执行第二个操作后 M={1,1,4,4,5,9}M=\{1,1,4,4,5,9\}M={1,1,4,4,5,9}

第三个操作查询 MMM 中第 111 小的数字,答案为 111

第四个操作查询 MMM999 的前驱,答案为 555

第五个操作查询 MMM 中有多少个数比 888 小,并且将答案加 111,答案为 666

第六个操作查询 MMM111 的后继,答案为 444

第七个操作完成后 M={0,1,1,4,4,5,9}M=\{0,1,1,4,4,5,9\}M={0,1,1,4,4,5,9}

输出 1⊕5⊕6⊕4=61\oplus5\oplus6\oplus4=61564=6
::::

限制与约定

对于 100%100\%100% 的数据,1≤n≤1051\leq n\leq 10^51n1051≤m≤1061\leq m\leq 10^61m1060≤ai,x<2300\leq a_i,x\lt 2^{30}0ai,x<230

本题输入数据较大,请使用较快的读入方式。


upd 2022.7.22\text{upd 2022.7.22}upd 2022.7.22:新增加 999 组 Hack 数据。

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+10;
const double ALPHA = 0.7;
typedef long long ll;
int n,m;
int head=0;
int cnt=0;
int key[N];
int key_cnt[N];
int ls[N];
int rs[N];
int sz[N];
int diff[N];
int collect[N];
int ci;
int top;
int fa;
int side;
int a[N];
int init(int num)
{key[++cnt]=num;ls[cnt] = rs[cnt] =0;key_cnt[cnt] = sz[cnt] = diff[cnt] = 1;return cnt;
}void up(int i)
{sz[i] = sz[ls[i]]+sz[rs[i]]+key_cnt[i];diff[i] = diff[ls[i]]+diff[rs[i]]+(key_cnt[i]>0?1:0);
}void inorder(int i)
{if(i!=0){inorder(ls[i]);if(key_cnt[i]>0)collect[++ci]=i;inorder(rs[i]);}
}int build(int l,int r)
{if(l>r)return 0;int m = (l+r)>>1;int h = collect[m];ls[h] = build(l,m-1);rs[h] = build(m+1,r);up(h);return h;
}void rebuild()
{if(top!=0){ci=0;inorder(top);if(ci>0){if(fa==0)head = build(1,ci);else if(side==1) ls[fa] = build(1,ci);else rs[fa] = build(1,ci);}}
}bool balance(int i)
{return ALPHA*diff[i]>=max(diff[ls[i]],diff[rs[i]]);
}void add(int i,int f,int s,int num)
{if(i==0){if(f==0)head = init(num);else if(s==1) ls[f] = init(num);else rs[f] = init(num);}else {if(key[i]==num)key_cnt[i]++;else if(key[i]>num)add(ls[i],i,1,num);else add(rs[i],i,2,num);}up(i);if(!balance(i)){top = i;fa = f;side = s;}
}void add(int num)
{top = fa = side = 0;add(head,0,0,num);rebuild();
}int small(int i,int num)
{if(i==0)return 0;if(key[i]>=num)return small(ls[i],num);else return sz[ls[i]]+key_cnt[i]+small(rs[i],num);
}int getRank(int num)
{return small(head,num)+1;
}int index(int i,int x)
{if(sz[ls[i]]>=x)return index(ls[i],x);else if(sz[ls[i]]+key_cnt[i]<x)return index(rs[i],x-sz[ls[i]]-key_cnt[i]);return key[i];
}int index(int x)
{return index(head,x);
}int pre(int num)
{int kth = getRank(num);if(kth==1)return INT_MIN;else return index(kth-1);
}int post(int num)
{int kth = getRank(num+1);if(kth==sz[head]+1)return INT_MAX;else return index(kth);
}void remove(int i,int f,int s,int num)
{if(key[i]==num)key_cnt[i]--;else if(key[i]>num)remove(ls[i],i,1,num);else remove(rs[i],i,2,num);up(i);if(!balance(i)){top = i;fa = f;side = s;}
}void remove(int num)
{if(getRank(num)!=getRank(num+1)){top = fa = side = 0;remove(head,0,0,num);rebuild();}
}void solve()
{cin>>n>>m;int ans=0;int lans=0;for(int i=1;i<=n;i++){int x;cin>>x;add(x);}for(int i=1;i<=m;i++){int op,x;cin>>op>>x;x^=lans;if(op==1)add(x);else if(op==2)remove(x);else if(op==3){lans=getRank(x);ans ^= lans;}else if(op==4){lans=index(x);ans^=lans;}else if(op==5){lans=pre(x);ans^=lans;}else if(op==6){lans=post(x);ans^=lans;}}cout<<ans<<endl;
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t=1;// cin>>t;while(t--){solve();}return 0;
}
http://www.dtcms.com/a/492560.html

相关文章:

  • 苏州外贸网站建设推广服务中交路桥建设网站
  • 网站出现的的问题wordpress主题和模板下载
  • 瑶海区网站建设公司广州app开发
  • 如何提升网站知名度千里马招标网站
  • 长沙网站搭建关键词排名外贸网站如何做推广多少钱
  • vs做的本地网站万创网站建设
  • dede网站5.7广告去除开发app的费用
  • 做设计用的素材下载网站有哪些广告设计图片 海报
  • Shell 基础知识点总结
  • 网站如何备案工信局备案网站打不开
  • 苏州网站建设空间河南省的网页制作
  • 网站开发的招标参数雅安网站建设公司
  • 企业站seo报价黑龙江省城乡和住房建设厅网站首页
  • 某公司人事管理网站开发wordpress建站不好用
  • 《独立开发者精选工具》
  • 注册网站需要多少钱wordpress很卡
  • 【大模型】IndexTTS-1.5在Linux + GTX1080TI平台部署步骤及性能分析
  • 比较好的网站建设品牌升级辽源商城网站建设
  • 纳税服务网站建设情况网络及建设公司网站
  • 用phpcms建站的网站深圳o2o网站建设
  • 网站建设公司发展方向及趋势网站内页产品 首页推荐
  • 做老托福听力的网站php做的网站 订单系统
  • 商派商城网站建设二次开发本地配置wordpress
  • 【论文学习】医学图像分割论文
  • 在网站做电子画册做的网站第二年续费多钱
  • 网站建设平台案例唯美wordpress简约主题
  • 购物网站建设ppt51游戏
  • 中国黄页是什么网站做进一步优化
  • 什么是MySQL分区?
  • 网站首页怎么用dw做服务器搭建网站能ping t