[cf1515H]Phoenix and Bits
记$V=2^{20}-1$,即值域范围,也可以作为"全集"
显然与$a_{i}$的顺序无关,对所有$a_{i}$维护一棵trie树
关于如何维护这棵trie树,考虑使用分裂+合并的方式,即:1.分裂出区间对应的trie树;2.操作分裂出的trie树;3.合并分裂出的tire树和原trie树
(关于时间复杂度后面会进行统一分析,暂时不需要考虑)
对于分裂(第1步),使用类似线段树查询的方法
对于合并(第3步),使用类似线段树合并的方法(即在其中一个子树为空时直接选择另一个子树)
对于操作(第2步),对不同的操作类型分类讨论——
查询操作:维护子树大小(子树内数值数量),直接输出即可
与操作:将其转化为异或$V$、或$x\oplus V$、异或$V$,那么只需要考虑异或和或操作即可
异或操作:直接在根节点上打懒标记,对于区间$[l,r]$的懒标记$tag$仅考虑$tag\and (r-l)$的结果,因此在下传标记时,若$tag\and \frac{r-l+1}{2}$非0则交换$[l,r]$的左右儿子
或操作:递归所有节点,当递归到区间$[l,r]$时,若$x\and \frac{r-l+1}{2}$非0则在$[l,r]$的左子树上打异或$\frac{r-l+1}{2}$的懒标记并合并$[l,r]$的左右子树(其中$x$为操作权值),再做如下剪枝——
维护子树与(子树内所有数值的与)和子树或,设当前子树两者分别为$v_{1}$和$v_{2}$,若$x\and (v_{1}\oplus v_{2}\oplus V)=x$(即子树内所有权值在$x$为1的位上都相同)则直接打上异或$x\and (v_{1}\oplus V)$的懒标记即可
("在$[l,r]$的左子树上打异或$\frac{r-l+1}{2}$的懒标记"的实际目的是维护子树与和子树或)
下面,来分析时间复杂度:
定义节点$x$的势能为$1+\log V+(v_{1}\oplus v_{2})$中1的个数(其中$v_{1}$和$v_{2}$为子树与和子树或,后者即$x$子树中仍未完全相同的位数),分别考虑这些操作的均摊复杂度——
分裂新建$o(\log V)$个节点,一个节点的势能为$o(\log V)$,即$o(\log^{2}V)$
合并递归过程中,若继续递归,即会合并两个节点,合并后势能减少$o(1)$,即均摊复杂度为$o(1)$
异或(打懒标记)不影响势能,即均摊复杂度为$o(1)$
或操作递归过程中,若不满足剪枝,必然会使得$v_{1}\oplus v_{2}$中1的个数减少1个,即均摊复杂度为$o(1)$
另外,势能和的范围显然也是$o(n\log^{2}V)$
综上所述,总均摊复杂度为$o(n\log^{2}V)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 8000005
4 #define V ((1<<20)-1)
5 #define mid (l+r>>1)
6 int V_trie,rt,n,m,p,x,y,z,ls[N],rs[N],sz[N],And[N],Or[N],tag[N];
7 int New(){
8 int k=++V_trie;
9 And[k]=V;
10 return k;
11 }
12 void upd_xor(int k,int l,int r,int x){
13 if (!k)return;
14 tag[k]^=x;
15 int p=((And[k]&(x^V))|((Or[k]^V)&x));
16 Or[k]=((Or[k]&(x^V))|((And[k]^V)&x));
17 And[k]=p;
18 }
19 void up(int k){
20 sz[k]=sz[ls[k]]+sz[rs[k]];
21 And[k]=(And[ls[k]]&And[rs[k]]);
22 Or[k]=(Or[ls[k]]|Or[rs[k]]);
23 }
24 void down(int k,int l,int r){
25 if (tag[k]&((r-l+1)>>1))swap(ls[k],rs[k]);
26 upd_xor(ls[k],l,mid,tag[k]);
27 upd_xor(rs[k],mid+1,r,tag[k]);
28 tag[k]=0;
29 }
30 void add(int &k,int l,int r,int x){
31 if (!k)k=New();
32 if (l==r){
33 sz[k]=1,And[k]=Or[k]=x;
34 return;
35 }
36 if (x<=mid)add(ls[k],l,mid,x);
37 else add(rs[k],mid+1,r,x);
38 up(k);
39 }
40 int split(int &k,int l,int r,int x,int y){
41 if ((!k)||(l>y)||(x>r))return 0;
42 if ((x<=l)&&(r<=y)){
43 int p=k;
44 k=0;
45 return p;
46 }
47 down(k,l,r);
48 int kk=New();
49 ls[kk]=split(ls[k],l,mid,x,y);
50 rs[kk]=split(rs[k],mid+1,r,x,y);
51 up(k),up(kk);
52 return kk;
53 }
54 void merge(int &k1,int k2,int l,int r){
55 if ((!k1)||(!k2)){
56 k1+=k2;
57 return;
58 }
59 if (l==r){
60 sz[k1]=max(sz[k1],sz[k2]);
61 And[k1]&=And[k2];
62 Or[k1]|=Or[k2];
63 return;
64 }
65 down(k1,l,r),down(k2,l,r);
66 merge(ls[k1],ls[k2],l,mid);
67 merge(rs[k1],rs[k2],mid+1,r);
68 up(k1);
69 }
70 void upd_or(int k,int l,int r,int x){
71 if (!k)return;
72 if ((x&(And[k]^Or[k]^V))==x){
73 upd_xor(k,l,r,(x&(And[k]^V)));
74 return;
75 }
76 down(k,l,r);
77 if (x&((r-l+1)>>1)){
78 upd_xor(ls[k],l,mid,((r-l+1)>>1));
79 merge(rs[k],ls[k],mid+1,r);
80 ls[k]=0;
81 }
82 upd_or(ls[k],l,mid,x);
83 upd_or(rs[k],mid+1,r,x);
84 up(k);
85 }
86 int main(){
87 scanf("%d%d",&n,&m);
88 And[0]=V;
89 for(int i=1;i<=n;i++){
90 scanf("%d",&x);
91 add(rt,0,V,x);
92 }
93 for(int i=1;i<=m;i++){
94 scanf("%d%d%d",&p,&x,&y);
95 int k=split(rt,0,V,x,y);
96 if (p==4)printf("%d\n",sz[k]);
97 else{
98 scanf("%d",&z);
99 if (p==1){
100 upd_xor(k,0,V,V);
101 upd_or(k,0,V,(z^V));
102 upd_xor(k,0,V,V);
103 }
104 if (p==2)upd_or(k,0,V,z);
105 if (p==3)upd_xor(k,0,V,z);
106 }
107 merge(rt,k,0,V);
108 }
109 }
[cf1515H]Phoenix and Bits的更多相关文章
- Phoenix综述(史上最全Phoenix中文文档)
个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...
- 在DBeaver中phoenix查询报错:org.apache.phoenix.exception.PhoenixIOException: The system cannot find the path specified
环境:Phoenix:4.4,win7系统 问题:Phoenix在查询hbase时,报"系统找不到指定路径". 解决: 请参见 https://distcp.quora.com/C ...
- [LeetCode] Number of 1 Bits 位1的个数
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...
- [LeetCode] Reverse Bits 翻转位
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...
- HBase+Phoenix整合入门--集群搭建
环境:CentOS 6.6 64位 hbase 1.1.15 phoenix-4.7.0-HBase-1.1 一.前置环境: 已经安装配置好Hadoop 2.6和jdk 1.7 二.安装hba ...
- 【leetcode】Number of 1 Bits
题目描述: Write a function that takes an unsigned integer and returns the number of '1' bits it has (als ...
- SQL Server恢复软件 Stellar Phoenix sql recovery
SQL Server恢复软件 Stellar Phoenix sql recovery http://www.stellarinfo.com/ http://www.stellarinfo.com/ ...
- Leetcode-190 Reverse Bits
#190. Reverse Bits Reverse bits of a given 32 bits unsigned integer. For example, given input 432615 ...
- CodeForces 485C Bits[贪心 二进制]
C. Bits time limit per test1 second memory limit per test256 megabytes inputstandard input outputsta ...
随机推荐
- Serverless 在 SaaS 领域的最佳实践
作者 | 计缘 来源 | Serverless 公众号 随着互联网人口红利逐渐减弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身持续增长的新蓝海,产业互联网正是这一宏大背景下的新趋势 ...
- 题解 Yet Another Number Sequence
题目传送门 Description 给出 \(n,k\) ,求出: \[\sum_{i=1}^{n} f_i·i^k \] 其中 \(f_i\) 表示斐波拉契第 \(i\) 项.\(n\le 10^{ ...
- CAD图DWG解析WebGIS可视化技术分析总结
背景 AutoCAD是国际上著名的二维和三维CAD设计软件,用于二维绘图.详细绘制.设计文档和基本三维设计.现已经成为国际上广为流行的绘图工具..dwg文件格式成为二维绘图的事实标准格式. 但由于Au ...
- Tomcat 源码环境搭建
Tomcat 源码搭建 下载源码 下载地址 :https://tomcat.apache.org/download-80.cgi#8.5.35 下载之后解压缩 导入Idea 添加pom.xml文件 & ...
- 初学python-day4 字典(已更新完)
- ThreadLocal部分源码分析
结构演进 早起JDK版本中,ThreadLocal内部结构是一个Map,线程为key,线程在"线程本地变量"中绑定的值为Value.每一个ThreadLocal实例拥有一个Map实 ...
- JavaScript中的模式匹配
JavaScript中的模式匹配 模式是用于转换输入数据的规则. 以将数据与一个或多个逻辑结构进行比较,将数据分解为各个构成部分,或以各种方式从数据中提取信息. 安装 JavaScript已经实现模式 ...
- 【数据结构与算法Python版学习笔记】引言
学习来源 北京大学-数据结构与算法Python版 目标 了解计算机科学.程序设计和问题解决的基本概念 计算机科学是对问题本身.问题的解决.以及问题求解过程中得出的解决方案的研究.面对一 个特定问题,计 ...
- Scrum Meeting 0501
零.说明 日期:2021-5-1 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 整装待发,准备冲刺 ...
- [no code][scrum meeting] Alpha 4
项目 内容 会议时间 2020-04-09 会议主题 OCR相关的技术展示与讨论 会议时长 30min 参会人员 全体成员 $( "#cnblogs_post_body" ).ca ...