BZOJ4942【noi2017】整数
luogu的题面
https://www.luogu.org/problemnew/show/P3822
题意:
x初始为0,维护+a*2^k ,其中a为整数,k为自然数;查询x的第k位;
题解:
①将数看成序列,线段树逐位维护。比较大,压位(下面的代码base=30,ls() rs()为左右儿子)。
②输入1,a,b,即将b/base号节点加 (a<<b%base)的base位以内部分,b/base+1号节点加 (a<<b%base)base位以上的部分。
③假设我们已经找到了b对应的叶子节点,修改后考虑进位。定义fg1[k]表示k节点是否是最大值(1<<base)-1,b对应的叶子往上跳一层到k号节点,如果fg1[rs(k)]==false,直接rs(k)里进位就好了,否则把rs(k)清零,再往上跳,退位同理(写的时候记得pushdown和pushup 。。。。TAT);
#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
//#define N 1000100
//#define base 30
#define ll long long
#define ls(k) (k<<1)
#define rs(k) (ls(k)|1)
using namespace std;
const ll base=,N=4.2e7/base,B=(<<base)-,len=4.1e7/base;
//const int B = (1<<base) - 1,len = 1e6 + 5;
int n,t1,t2,t3;
int w[N<<],fg1[N<<],fg0[N<<],ly1[N<<],ly0[N<<];
char gc(){
static char *p1,*p2,s[];
if(p1==p2) p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x = ,f = ; char c = gc();
while(c<''||c>'') {if(c=='-') f = -; c = gc();}
while(c>=''&&c<='') {x = x * + c - ''; c = gc();}
return x * f;
}
void pushup(int k){
int l = ls(k),r = rs(k);
fg0[k] = fg0[l] && fg0[r];
fg1[k] = fg1[l] && fg1[r];
}
void mdf(int k,int typ){
w[k] = B * typ;
fg1[k] = ly1[k] = typ;
fg0[k] = ly0[k] = !typ;
}
void pushdown(int k){
int l = ls(k),r = rs(k);
if(ly0[k]) mdf(l,),mdf(r,),ly0[k] = ;
if(ly1[k]) mdf(l,),mdf(r,),ly1[k] = ;
}
void change(int k,int l,int r,int typ){
if(l==r) {
w[k]+=typ;
fg0[k] = !w[k];
fg1[k] = (w[k]==B);
}
else{
if(ly0[k]||ly1[k]) pushdown(k);
int mid = (l+r)>>;
if(typ==){
if(!fg1[ls(k)]) change(ls(k),l,mid,);
else mdf(ls(k),),change(rs(k),mid+,r,);
}
else{
if(!fg0[ls(k)]) change(ls(k),l,mid,-);
else mdf(ls(k),),change(rs(k),mid+,r,-);
}
pushup(k);
}
}
int update(int k,int l,int r,int x,int y){
if(!y) return ;
int typ = ;
if(l==r) {
w[k] += y;
if(w[k]>=(<<base)) w[k] -= (<<base),typ = ;
else if(w[k]<) w[k] += (<<base),typ = -;
fg0[k] = !w[k];
fg1[k] = (w[k]==B);
}
else {
if(ly0[k]||ly1[k]) pushdown(k);
int mid = (l + r)>>;
if(x<=mid){
typ = update(ls(k),l,mid,x,y);
if(typ==) {
if(!fg1[rs(k)]) typ = ,change(rs(k),mid+,r,);
else mdf(rs(k),);
}
if(typ==-){
if(!fg0[rs(k)]) typ = ,change(rs(k),mid+,r,-);
else mdf(rs(k),);
}
}
else typ = update(rs(k),mid+,r,x,y);
pushup(k);
}
return typ;
}
int query(int k,int l,int r,int x,int y){
if(l==r) return bool(w[k]&y);
else {
if(ly0[k]||ly1[k]) pushdown(k);
int mid = (l + r)>>;
if(x<=mid) return query(ls(k),l,mid,x,y);
else return query(rs(k),mid+,r,x,y);
}
}
int main()
{ //freopen("mzoj1111.in","r",stdin);
//freopen("mzoj1111.out","w",stdout);
n = rd(); t1 = rd(); t2 = rd(); t3 = rd();
fg0[] = ly0[] = ;
for(int i = ;i <= n;i++){
ll opt = rd(),f,a,b,x,y;
if(opt&){
a = rd(); b = rd();
if(a<) a*=-,f=-; else f=;
a <<= (b%base); b /= base;
update(,,len,b,f*(a&B));
update(,,len,b+,f*(a>>base));
}
else{
x = rd();
y = <<(x%base); x /= base;
int ans = query(,,len,x,y);
printf("%d\n",ans);
}
}
return ;
}//by tkys_Austin;
BZOJ4942【noi2017】整数的更多相关文章
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- [BZOJ4942] [NOI2017]整数
题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...
- BZOJ4942 NOI2017整数(线段树)
首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...
- 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)
传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...
- [BZOJ4942][Noi2017]整数 线段树+压位
用线段树来模拟加减法过程,维护连续一段中是否全为0/1. 因为数字很大,我们60位压一位来处理. #include<iostream> #include<cstring> #i ...
- 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...
- 【BZOJ4942】[NOI2017]整数(分块)
[BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...
- [NOI2017]整数
[NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...
- NOI2017整数
NOI2017 整数 题意: 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...
- 【bzoj4942】[Noi2017]整数 压位+线段树
题目描述 P 博士将他的计算任务抽象为对一个整数的操作. 具体来说,有一个整数 $x$ ,一开始为0. 接下来有 $n$ 个操作,每个操作都是以下两种类型中的一种: 1 a b :将 $x$ 加上整数 ...
随机推荐
- 关于jvm的OutOfMemory:PermGen space异常的解决
在做网校的时候,经常会在控制台会报出方法区的内存溢出,在网上找的方法,无非都是在tomcat的bin/catalina.bat文件中 设置jvm的堆的大小和方法区的大小,但是通过eclipse启动to ...
- DML数据操作语言之查询(二)
当我们查询出了N条记录之后 ,我们知道一共是几条记录,或者这些记录某一字段(列值)的最大值,最小值,平均值等,就可以使用聚合函数. 1.聚合函数 聚合函数会将null 排除在外.但是count(*)例 ...
- 第5章 子网划分和CIDR
第5章 子网划分和CIDR 划分网络 根据A类.B类或C类网络ID来识别网段具有一些局限性,主要是在网络级别之下不能对地址空间进行任何逻辑细分 如果一个IP是一个A类网络.数据报到达网关,然后传输到9 ...
- 多台linux主机之间建立免密通信
多台linux主机之间设置免密通信 例:A 向 B设置免密通信 第一步 A生成密钥对 ssh-keygen -t rsa -t 指定秘钥的类型 rsa 秘钥类型 密钥目录:/root/.ssh/(如果 ...
- Python内置函数(64)——classmethod
英文文档: classmethod(function) Return a class method for function. A class method receives the class as ...
- Spring知识点回顾(08)spring aware
Spring知识点回顾(08)spring aware BeanNameAware 获得容器中的bean名称 BeanFactoryAware 获得当前的bean factory Applicatio ...
- Docker学习笔记 - 在运行中的容器内启动新进程
docker psdoker top dc1 # 容器情况# 在运行中的容器内启动新进程docker exec [-d] [-i] [-t] 容器名 [command] [args]docker ex ...
- 新概念英语(1-55)The Sawyer family
新概念英语(1-55)The Sawyer family When do the children do their homework? The Sawyers live at 87 King Str ...
- 九、Python+Selenium模拟用QQ登陆腾讯课堂,并提取报名课程(练习)
研究QQ登录规则的话,得分析大量Javascript的加密解密,比较耗时间.自己也是练习很少,短时间成功不了.所以走了个捷径. Selenium是一个WEB自动化测试工具,它运行时会直接实例化出一个浏 ...
- 关于PHP包含文件的方法
Begin 今天陆陆续续在重新写一些后台程序,用到了一些共用的PHP文件,所以顺便学习了一下几种包含文件方式 include 最常用的包含文件方法,如果遇到错误会显示warning,但是不会影响下面脚 ...