压 位 T r i e 入 门 练 习 题(确信)

题意很清楚(

让我们先来想一想,如果没有排序操作的话,这道题应该怎么做。

我们维护一个 \(x\) 表示从开始到现在一共异或上了 \(x\),在序列末尾插入一个 \(n\) 相当于插入 \(n \bigoplus x\)。

现在的问题就是:

  1. 询问 \(\sum_{i=l}^ra_i \bigoplus x\)
  2. 改变 \(x\)。

位运算相关的还是考虑按位拆分比较好。

如果我们能够知道这个区间中的第 \(k\) 位有多少个 \(1\),似乎就能够 \(O(k)\) 计算这一位对答案的贡献了。

于是我们使用一颗线段树来维护这个序列,每个位置开一个 \(\log V\) 的数组来维护这个东西,插入和询问的复杂度均为 \(O(\log n\log V)\)。

那么我们加上排序操作?

众所周知 01trie 就是线段树,于是我们先把线段树改成 01trie。

我们发现异或上一个数可以看做将某几层的左儿子和右儿子交换。

然后在询问的时候搞清楚这一层有没有交换左右儿子,然后判断究竟该走哪边和该加上哪边就行了。

至于实现的话,对排序后的部分开一颗 01trie,未排序的部分直接使用前缀和统计。

时空复杂度都是 \(O((n+m)\log^2V)\)。

然而你发现这样算下来大概是 660MB,会被卡空间。。。

如果我们能够将 01trie 的节点数量减少,那么我们就可以把空间压下来了。

所以我们将 01trie 改成压两位的 压位 trie(也就是每个节点的度数为 \(4\)),空间就可以除以 \(2\) 了。

因为儿子个数并不是瓶颈,可以通过。

虽然说吧,你可以去赌 lxl 的插入操作很少,但是这明显还是会被卡(

以及细节巨多,需要判相同的数,还要判断我在什么时候异或上了多少。

#include<cstdio>
typedef unsigned ui;
const ui M=1e5+5,N=M*32;
ui n,m,cnt,k,tk,l1,l2,rt,ans[31],a[M<<1],S[M<<1][31];ui L,X[2];
struct Node{
ui sz,chi[4],ans[31];
inline ui&operator[](const ui&x){
return chi[x];
}
}t[N];
inline void swap(ui&a,ui&b){
ui c=a;a=b;b=c;
}
ui Find(const ui&u,ui x,const ui&id=14){
if(!u)return X[L++]=x,0;if(!~id)return X[L++]=x,0;const ui&k=tk>>(id<<1)&3;
if(x<=t[t[u][0^k]].sz)return Find(t[u][0^k],x,id-1)|0<<(id<<1);x-=t[t[u][0^k]].sz;
if(x<=t[t[u][1^k]].sz)return Find(t[u][1^k],x,id-1)|1<<(id<<1);x-=t[t[u][1^k]].sz;
if(x<=t[t[u][2^k]].sz)return Find(t[u][2^k],x,id-1)|2<<(id<<1);x-=t[t[u][2^k]].sz;
if(x<=t[t[u][3^k]].sz)return Find(t[u][3^k],x,id-1)|3<<(id<<1);x-=t[t[u][3^k]].sz;
}
void Qry(const ui&u,const ui&l,const ui&r,const ui&L=0,const ui&R=(1<<30)-1,const ui&id=14){
if(!u||l>R||L>r)return;
if(l<=L&&R<=r){
for(ui i=0;i<=30;++i)ans[i]+=t[u].ans[i];return;
}
ui k=tk>>(id<<1)&3,m1,m2,m3;m2=L+R>>1;m1=L+m2>>1;m3=m2+1+R>>1;
Qry(t[u][0^k],l,r,L,m1,id-1);Qry(t[u][1^k],l,r,m1+1,m2,id-1);
Qry(t[u][2^k],l,r,m2+1,m3,id-1);Qry(t[u][3^k],l,r,m3+1,R,id-1);
}
void Insert(const ui&x){
ui u=rt,id=14;
while(~id){
++t[u].sz;for(ui i=0;i<=30;++i)if(x>>i&1)++t[u].ans[i];
if(!t[u][x>>(id<<1)&3])t[u][x>>(id<<1)&3]=++cnt;u=t[u][x>>(id<<1)&3];--id;
}
++t[u].sz;for(ui i=0;i<=30;++i)if(x>>i&1)++t[u].ans[i];
}
inline void ins(const ui&x,const ui&id){
for(ui i=0;i<=30;++i)S[id][i]=S[id-1][i]+(x>>i&1);a[id]=x;
}
signed main(){
ui i,x,l,r,q,p,opt;unsigned long long sum;scanf("%u",&n);rt=++cnt;
for(i=1;i<=n;++i)scanf("%u",&x),ins(x,++l2);
scanf("%u",&m);
while(m--){
scanf("%u",&opt);
if(opt==1){
scanf("%u",&x);ins(x^k,++l2);
}
if(opt==2){
scanf("%u%u",&l,&r);for(i=0;i<=30;++i)ans[i]=0;sum=0;
if(r<=l1){
q=Find(rt,l);p=Find(rt,r);Qry(rt,q,p-1);--X[0];
for(i=0;i<=30;++i)sum+=1ull*(k>>i&1?r-l+1+X[0]-X[1]-ans[i]:ans[i])<<i;
sum+=1ull*(p^k^tk)*X[1];sum-=1ull*(q^k^tk)*X[0];
}
if(l<=l1&&l1<r){
q=Find(rt,l);Qry(rt,q,(1<<30)-1);--X[0];
for(i=0;i<=30;++i)sum+=1ull*(k>>i&1?l1-l+1+X[0]-ans[i]:ans[i])<<i;
for(i=0;i<=30;++i)sum+=1ull*(k>>i&1?r-l1-S[r-l1][i]:S[r-l1][i])<<i;
sum-=1ull*(q^k^tk)*X[0];
}
if(l1<l){
r-=l1;l-=l1;
for(i=0;i<=30;++i)sum+=1ull*(k>>i&1?r-l+1-(S[r][i]-S[l-1][i]):(S[r][i]-S[l-1][i]))<<i;
}
printf("%llu\n",sum);::L=0;
}
if(opt==3){
scanf("%u",&x);k^=x;
}
if(opt==4){
for(i=1;i<=l2;++i)Insert(a[i]);l1+=l2;tk=k;l2=0;
}
}
}

LGP5312题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. Ubuntu 18.04 修改默认源为国内源

    1.备份/etc/apt/sources.list #备份 cp /etc/apt/sources.list /etc/apt/sources.list.bak 2.在/etc/apt/sources ...

  2. 开源项目实现多线程下载 (xutils)

    public void download(View v){         EditText et_url = (EditText) findViewById(R.id.et_url);        ...

  3. 让我一时不知所措 Linux 常用命令 爱情三部曲 下部

    Linux目录与文件管理 我试着把你忘记,可总在夜里想你~ 1.linux目录结构 2.查看及检索文件 3.压缩及解压缩文件 4.vi文本编辑器 1.Linux目录结构:树形目录结构根目录:所有分区, ...

  4. Docker之LNMP分布式容器部署

    Docker之LNMP分布式容器部署 目录 Docker之LNMP分布式容器部署 一.项目模拟 1. 项目环境 2. 服务器环境 3. 任务需求 二.Linux系统基础镜像 三.Nginx 1. 建立 ...

  5. c++ 堆栈和内存管理

    stack(栈),heap(堆) Stack:是存在于某作用域(scope)的一个内存空间(memory space).例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,返回地址 ...

  6. serverless入门介绍

    1.什么是serverless Serverless 架构作为一种新型的云计算范式,是云原生时代一种革命性的架构,颠覆了传统意义上对软件应用部署和运营的认识.本节对 Serverless 架构的基本概 ...

  7. 【JOISC 2020 补题记录】

    目录 Day 1 Building 4 Hamburg Steak Sweeping Day 2 Chameleon's Love Making Friends on Joitter is Fun R ...

  8. RISC-V 特权指令结构

    机器模式 机器模式(缩写为 M 模式,M-mode)是 RISC-V 中 hart(hardware thread,硬件线 程)可以执行的最高权限模式.在 M 模式下运行的 hart 对内存,I/O ...

  9. python中的第一行#!

    一般python脚本的开通会写成 #! /usr/bin/python 这表示用/usr/bin目录下的这个python可执行文件来进行运行脚本 当然如果你还安装了其他版本的python,可以将第一行 ...

  10. Java IO模型:BIO、NIO、AIO

    Java IO模型:BIO.NIO.AIO 本来是打算直接学习网络框架Netty的,但是先补充了一下自己对Java 几种IO模型的学习和理解.分别是 BIO.NIO.AIO三种IO模型. IO模型的基 ...