记$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的更多相关文章

  1. Phoenix综述(史上最全Phoenix中文文档)

    个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...

  2. 在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 ...

  3. [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 ...

  4. [LeetCode] Reverse Bits 翻转位

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  5. HBase+Phoenix整合入门--集群搭建

    环境:CentOS 6.6 64位    hbase 1.1.15  phoenix-4.7.0-HBase-1.1 一.前置环境: 已经安装配置好Hadoop 2.6和jdk 1.7 二.安装hba ...

  6. 【leetcode】Number of 1 Bits

    题目描述: Write a function that takes an unsigned integer and returns the number of '1' bits it has (als ...

  7. SQL Server恢复软件 Stellar Phoenix sql recovery

    SQL Server恢复软件 Stellar Phoenix sql recovery http://www.stellarinfo.com/ http://www.stellarinfo.com/ ...

  8. Leetcode-190 Reverse Bits

    #190. Reverse Bits Reverse bits of a given 32 bits unsigned integer. For example, given input 432615 ...

  9. CodeForces 485C Bits[贪心 二进制]

    C. Bits time limit per test1 second memory limit per test256 megabytes inputstandard input outputsta ...

随机推荐

  1. tomcat启动程序报错

    1.问题 23-Apr-2021 10:53:38.897 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.de ...

  2. 将Oracle数据库数据每天备份恢复一次数据到另一台服务器上两份数据

    1.创建用户,授权,创建测试数据 创建用户 CREATE USER test identified by 123; 授权 grant dba to test; 创建测试数据 create table ...

  3. 微信小程序_快速入门02

    01我们学习了环境的准备和简单的demo,现在是时候来学习简单的页面编写了,首先我们来学习一些常用的基础标签: 一.view盒子,就是类似于div的盒子,可以用来存其他元素的容器. 二.text 文本 ...

  4. 2020.4.6--UCF Local Programming Contest 2017的正式赛

    Problem A : Electric Bill 题目大意:进行电量分级制收费,1000kwh及以下一档收费,1000kwh以上按另一档收费,给出每个人的电量总额,问每人应支付多少钱. 思路:基础i ...

  5. 个人记录:对于python学习的反思和总结(一)

    在写代码时,总是遇到写着写着不知道怎么写了的情况,或者无法把自己的想法用程序表达出来,所以有时候我们需要建立一个自己的编程思路,对一个具体程序的编程有一个比较清晰的想法:因此我把自己的思路总结了一下, ...

  6. DOM的本质 和 方法

    <JavaScript DOM编程艺术> 读书笔记 一句话解释DOM: DOM,即我们所看到的网页,其在浏览器背后的文档结构(树状分支结构),涵盖了每一个节点(称之为对象).可以通过JS等 ...

  7. 【UE4 C++】Print、Delay、ConsoleCommand

    基于UKismetSystemLibrary PrintString /** * Prints a string to the log, and optionally, to the screen * ...

  8. django-admin和django-admin.py的区别

    问题 django初学者在使用django-admin创建项目时容易出现无法创建的错误,这是因为网上很多教程用的都是django-admin.py创建的项目,不出意外的话,你输入相同的命令会发现项目没 ...

  9. try-catch-finally面试题

    try catch finally 执行顺序面试题总结 执行顺序 今天牛客网遇到这个题目,做对了,但是下面的评论却很值得看看 public class TestTry { public int add ...

  10. 封装一个简单的ajax请求

    记录自己第一次封装ajax,肯定有很多考虑不周到,如有错误请指出,本人必将虚心改正. /** * * @param {Object} obj =>header:请求头:url:请求地址:meth ...