[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 | Serverless Kubernetes 应用部署及扩缩容
作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...
- Spring Boot引入Swagger并对界面进行美化
Swagger是一个接口文档生成工具,在前后端分离的开发中经常会用到,下面就来介绍下Swagger的使用: 引入依赖 <dependency> <groupId>io.spri ...
- 学校选址(ArcPy实现)
一.背景 合理的学校空间位置布局,有利于学生的上课与生活.学校的选址问题需要考虑地理位置.学生娱乐场所配套.与现有学校的距离间隔等因素,从总体上把握这些因素能够确定出适宜性比较好的学校选址区. 二.目 ...
- NOIP模拟79
T1 F 解题思路 因为每个点会产生贡献当且仅当它在可以到他的点之前被删除,并且此题遵守期望的线性性. 因此设所有可以到达点 \(i\) 的数量为 \(c_i\) 那么答案就是 \(\sum \fra ...
- MyBatis 中实现SQL语句中in的操作 (11)
MyBatis 中实现SQL语句中in的操作 概括:应用myBatis实现SQL查询中IN的操作 1.数据库结构及其数据 2.mapper.xml文件 <?xml version="1 ...
- 【原创】浅谈指针(五)const和指针
前言 过了几个月再次更新.最近时间也不多了,快要期中考试了,暂且先少写一点吧. 本文仅在博客园发布,如在其他平台发现均为盗取,请自觉支持正版. 练习题 我们先来看几道题目.如果这几道题都不会的话,就先 ...
- 安装pytorch后import torch显示no module named 'torch'
问题描述:在pycharm终端里通过pip指令安装pytorch,显示成功安装但是python程序和终端都无法使用pytorch,显示no module named 'torch'. 起因:电脑里有多 ...
- 为什么阿里巴巴开发手册中强制要求 POJO 类使用包装类型?NPE问题防范
封面:学校内的秋天 背景:写这个的原因,也是我这两天凑巧看到的,虽然我一直有 alibaba Java 开发手册,也看过不少次,但是一直没有注意过这个问题 属于那种看过,但又没完全看过 一起来看看吧冲 ...
- DDL_Killer Alpha版本 Bug集中反馈处
本博客用于DDL_Killer Alpha版本的Bug集中反馈. 您可以在本博客的下方评论区处留言,反馈您在使用DDl_Killer的过程中遇到的问题,以帮助我们更好的改进本产品. 我们会尽快修复找到 ...
- Hadoop的HA(ZooKeeper)安装与部署
非HA的安装步骤 https://www.cnblogs.com/live41/p/15467263.html 一.部署设定 1.服务器 c1 192.168.100.105 zk.name ...