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】整数的更多相关文章

  1. [Bzoj4942][Noi2017]整数(线段树)

    4942: [Noi2017]整数 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 237[Submit][Status][D ...

  2. [BZOJ4942] [NOI2017]整数

    题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...

  3. BZOJ4942 NOI2017整数(线段树)

    首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...

  4. 2018.10.30 bzoj4942: [Noi2017]整数(线段树压位)

    传送门 直接把修改的数拆成logloglog个二进制位一个一个修改是会TLETLETLE的. 因此我们把303030个二进制位压成一位储存在线段树里面. 然后维护区间中最靠左二进制位不为0/1的下标. ...

  5. [BZOJ4942][Noi2017]整数 线段树+压位

    用线段树来模拟加减法过程,维护连续一段中是否全为0/1. 因为数字很大,我们60位压一位来处理. #include<iostream> #include<cstring> #i ...

  6. 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

    [BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...

  7. 【BZOJ4942】[NOI2017]整数(分块)

    [BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...

  8. [NOI2017]整数

    [NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...

  9. NOI2017整数

    NOI2017 整数 题意: ​ 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...

  10. 【bzoj4942】[Noi2017]整数 压位+线段树

    题目描述 P 博士将他的计算任务抽象为对一个整数的操作. 具体来说,有一个整数 $x$ ,一开始为0. 接下来有 $n$ 个操作,每个操作都是以下两种类型中的一种: 1 a b :将 $x$ 加上整数 ...

随机推荐

  1. 一个毕生难忘的BUG

    记得以前接手过一个Java项目,服务器程序,直接让Jar在linux上跑的那种, 这个项目由两个web服务组成,也就是两条Java进程,主进程 xxx.jar,辅助进程 xxx_helper.jar. ...

  2. caffe实现GAN

    我实现GAN网络结构比较复杂: 通过建立两个一模一样的网络,他们相对应的层共享权重,一个网络用来跟新D model另一个网络用来更新G model 更新G model的网络,D部分只进行梯度传递,不进 ...

  3. 第二篇:利用shell脚本执行webservice请求——基于soap

    1. 项目背景 以往我们在开发基于webservice的项目中,我们总习惯于直接使用webservice的一些框架,如Axis,axis2和Xfire等.框架的好处是将webservice所涉及到的s ...

  4. nyoj 数的长度

    描述 N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)······*2*1.现在你的任务是计算出N!的位数有多少(十进制)?   输入 首行输入n,表示有多少组测试数据(n<1 ...

  5. JAVA_SE基础——29.构造函数

    黑马程序员入学Blog... jvm创建Java对象时候需要调用构造器,默认是不带参数的.在构造器中,你可以让jvm帮你初始化一些参数或者执行一系列的动作. 它是对象创建中执行的函数,及第一个被执行的 ...

  6. lua保存table到文件并从文件解析成table

    require("json") result = { ["ip"]="192.168.0.177", ["date"]= ...

  7. HTTP头HOST

    http request header 中的host行的作用 在早期的Http 1.0版中,Http 的request请求头中是不带host行的,在Http 1.0的加强版和Http 1.1中加入了h ...

  8. api-gateway实践(01)服务网关 - 原型功能

    一.服务注册 1.增加组:LsqGrpA 2.增加版本:LsqVerA 3.增加api:LsqApiA 3.1.基本信息 3.2.前端定义 3.3.后端定义 二.服务上线和服务授权 1.服务上线 2. ...

  9. NHibernate的基本使用

    一.O/R Mapping 概论 工厂模式+反射+每个数据库的DAL层来解决数据访问层的代码 针对数据库表中字段的变化我们是无法预料的,所以每一次用户需求的修改都会直接导致我们程序员来修改—实体类(B ...

  10. Properties文件中文属性读取是乱码问题

    项目当中遇到了需要从Properties文件中读取配置属性的需求,本来是存储的中文转码后的属性,但是考虑到后期更改问题就变成java代码中进行转码,代码如下: Properties pros = ne ...