LGP5312题解
压 位 T r i e 入 门 练 习 题(确信)
题意很清楚(
让我们先来想一想,如果没有排序操作的话,这道题应该怎么做。
我们维护一个 \(x\) 表示从开始到现在一共异或上了 \(x\),在序列末尾插入一个 \(n\) 相当于插入 \(n \bigoplus x\)。
现在的问题就是:
- 询问 \(\sum_{i=l}^ra_i \bigoplus x\)
- 改变 \(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题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- bom-倒计时
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Redis——(主从复制、哨兵模式、集群)的部署及搭建
Redis--(主从复制.哨兵模式.集群)的部署及搭建 重点: 主从复制:主从复制是高可用redis的基础,主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复. 哨兵和集群都是 ...
- 【第十八期】分享一个网易go面经
自我介绍 未来的主要方向 介绍下之前的项目用到的优化点.难点 为什么不要大量使用goroutine gpm模型 go里面goroutine创建数量有限制吗? 线程和协程有什么区别 golang支持哪些 ...
- 系统操作命令实践 下(系统指令+增删改查+vim编辑器)
目录 1.考试 2.今日问题 3.今日内容 4.复制文件 4.移动文件 Linux文件查看补充 cat , nl 5.删除文件 6.系统别名 7.vi/vim编辑器 系统操作命令实践 下(系统指令+增 ...
- verification 时间不推进,挂起
时间不推进,挂起 0时刻 windows-> new -> source Browser 可能是仿真精度不够,比如进度是1ns,但是时钟有0.1ns为周期的,这种情况下,仿真器会吧这个周期 ...
- Redis 源码简洁剖析 13 - RDB 文件
RDB 是什么 RDB 文件格式 Header Body DB Selector AUX Fields Key-Value Footer 编码算法说明 Length 编码 String 编码 Scor ...
- C# 实例解释面向对象编程中的里氏替换原则
在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...
- Python小游戏之 - 飞机大战 !
用Python写的"飞机大战"小游戏 源代码如下: # coding=utf-8 import random import os import pygame # 用一个常量来存储屏 ...
- 自动同步bing壁纸
在百度搜东西,经常出来一大坨广告:要么就是复制粘贴文章.完全没有创新,搜索越来越困难.偶尔用一下bing还挺好用. bing的壁纸是真心好看,每天不重样.决定写个脚本同步一下它的壁纸. 一.以我的Wi ...
- C#控制树莓派入门
何为树莓派 许久没有写博客了,十二月份西安疫情的影响,居家隔离了一个多月,在其期间,学习了一下树莓派,觉得硬件还是挺有意思的,刚好也看到了巨硬有提供使用c#用来开发树莓派应用的解决方案叫Net Iot ...