首先把每32位压成一个unsigned int(当然只要压起来能过就行)。如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了。那么考虑如何维护进/退位。可以发现进位的过程其实就是将一段连续的inf改为0,并把之后一位+1,也就是说只要找到某一位之后第一个不是inf的位就好了。我们用线段树维护这个东西,记录一下某个节点表示的区间是否全为inf。查询时先从叶子节点往上爬,直到当前节点代表的区间中在该叶子节点右边的位不全为inf时停止,之后再往下找最左的非inf位。退位类似。这样的话复杂度就是O(nlogn)。

  写起来挺烦的,注意一下各种细节,码力极弱选手表示调了快一天……惨惨。

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 1000010
#define ui unsigned int
#define inf 4294967295
#define lson (k<<1)
#define rson (k<<1|1)
#define getmid; int mid=tree[k].l+tree[k].r>>1;
int n;
struct data{int l,r,tag,size,sumzero,suminf;ui num;
}tree[N<<];
bool isleaf(int k){return tree[k].size==;}
void build(int k,int l,int r)
{
tree[k].l=l,tree[k].r=r,tree[k].size=r-l+;
tree[k].sumzero=tree[k].size,tree[k].suminf=;
if (isleaf(k)) return;
getmid;
build(lson,l,mid);
build(rson,mid+,r);
}
void up(int k)
{
tree[k].sumzero=tree[lson].sumzero+tree[rson].sumzero;
tree[k].suminf=tree[lson].suminf+tree[rson].suminf;
}
void update(int k,int tag)
{
if (tag>) tree[k].sumzero=tree[k].size,tree[k].suminf=;
else tree[k].sumzero=,tree[k].suminf=tree[k].size;
tree[k].tag=tag;
if (isleaf(k)) tree[k].num=tag>?:inf;
}
void down(int k)
{
if (tree[k].tag)
{
update(lson,tree[k].tag);
update(rson,tree[k].tag);
tree[k].tag=;
}
}
int find(int k,int x)
{
if (isleaf(k)) return k;
down(k);
getmid;
int ans;
if (x<=mid) ans=find(lson,x);
else ans=find(rson,x);
up(k);
return ans;
}
void modify(int k,int l,int r,int tag)
{
if (tree[k].l==l&&tree[k].r==r)
{
update(k,tag);
return;
}
down(k);
getmid;
if (r<=mid) modify(lson,l,r,tag);
else if (l>mid) modify(rson,l,r,tag);
else modify(lson,l,mid,tag),modify(rson,mid+,r,tag);
up(k);
}
int add(int k,int p,ui x)
{
if (isleaf(k))
{
int v=inf-tree[k].num<x;
tree[k].num+=x;
tree[k].sumzero=(tree[k].num==);
tree[k].suminf=(tree[k].num==inf);
return v;
}
down(k);
getmid;
int ans;
if (p<=mid) ans=add(lson,p,x);
else ans=add(rson,p,x);
up(k);
return ans;
}
int dec(int k,int p,ui x)
{
if (isleaf(k))
{
int v=tree[k].num<x;
tree[k].num-=x;
tree[k].sumzero=(tree[k].num==);
tree[k].suminf=(tree[k].num==inf);
return v;
}
down(k);
getmid;
int ans;
if (p<=mid) ans=dec(lson,p,x);
else ans=dec(rson,p,x);
up(k);
return ans;
}
void pushup(int k)
{
if (tree[k].suminf)
{
int t=k,cnt=;
while (tree[k].suminf-cnt==tree[k].r-tree[t].l+)
{
if (k&) cnt+=tree[k-].suminf;
k>>=;
}
k=rson;
while (!isleaf(k))
{
down(k);
if (tree[lson].suminf==tree[lson].size) k=rson;
else k=lson;
}
modify(,tree[t].l,tree[k].l-,);
}
add(,tree[k].l,);
}
void pushdown(int k)
{
if (tree[k].sumzero)
{
int t=k,cnt=;
while (tree[k].sumzero-cnt==tree[k].r-tree[t].l+)
{
if (k&) cnt+=tree[k-].sumzero;
k>>=;
}
k=rson;
while (!isleaf(k))
{
down(k);
if (tree[lson].sumzero==tree[lson].size) k=rson;
else k=lson;
}
modify(,tree[t].l,tree[k].l-,-);
}
dec(,tree[k].l,);
}
int query(int k,int p,int x)
{
if (isleaf(k)) return tree[k].num>>x&;
down(k);
getmid;
int ans;
if (p<=mid) ans=query(lson,p,x);
else ans=query(rson,p,x);
up(k);
return ans;
}
int main()
{
n=read();read(),read(),read();
build(,,n+);
for (int i=;i<=n;i++)
{
int op=read();
if (op==)
{
int x=read(),y=read();
if (x>)
{
ui v=x;
ui a=v<<(y&),b=(y&)?(v>>(-(y&))):;
if (a>) b+=add(,(y>>)+,a);
if (b>)
{
a=add(,(y>>)+,b);
if (a>) pushup(find(,(y>>)+));
}
}
else
{
ui v=abs(x);
ui a=v<<(y&),b=(y&)?(v>>(-(y&))):;
if (a>) b+=dec(,(y>>)+,a);
if (b>)
{
a=dec(,(y>>)+,b);
if (a>) pushdown(find(,(y>>)+));
}
}
}
else
{
int x=read();
printf("%d\n",query(,(x>>)+,x&));
}
}
return ;
}

BZOJ4942 NOI2017整数(线段树)的更多相关文章

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

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

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

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

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

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

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

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

  5. UOJ #314. 【NOI2017】整数 | 线段树 压位

    题目链接 UOJ 134 题解 可爱的电音之王松松松出的题--好妙啊. 首先想一个朴素的做法! 把当前的整数的二进制当作01序列用线段树维护一下(序列的第i位就是整数中位权为\(2^k\)的那一位). ...

  6. noi2017 T1 整数 ——线段树

    loj.ac上有  题目传送门 不过我还是把题目搬过来吧 整数(integer)[题目背景]在人类智慧的山巅,有着一台字长为 1048576 位的超级计算机,著名理论计算机科 学家 P 博士正用它进行 ...

  7. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

  8. 【noi2017】 整数 线段树or模拟

    ORZYYB 题目大意:你需要维护一个有$3\times 10^7$个二进制位的数,有一种修改方式和一种询问方式 对这个数加上$a\times2^b$,其中$|a|≤10^9$,$b≤3\times ...

  9. [BZOJ4942] [NOI2017]整数

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

随机推荐

  1. Centos7下完美安装并配置mysql5.6

    Centos7将默认数据库mysql替换成了Mariadb,对于我们这些还想用mysql的人来说并不是一个好消息. 最近我搜罗了网上各种安装教程,各种出问题,要么安装失败,要么安装成功了却使用不了my ...

  2. 17-(基础入门篇)GPRS(Air202)串口

    https://www.cnblogs.com/yangfengwu/p/9968716.html 现在看一下官方给的demo 其实只要有两个就好说了 module(...,package.seeal ...

  3. flask seesion组件

    一.简介     flask中session组件可分为内置的session组件还有第三方flask-session组件,内置的session组件功能单一,而第三方的flask-sessoin可支持re ...

  4. Ubuntu16.04密码正确 进不去桌面系统(已测试恢复正常)

    遇到过两次ubuntu输入密码正确,但是进不去系统,输入密码后,跳转到一下界面 之后又返回到登陆界面,一直这样循环输入密码. Guest用户可以.   解决办法: 1.进入tty下           ...

  5. 将当前的Ubuntu系统封装成为可以安装(发布)的iso镜像

    将当前的Ubuntu系统封装成为可以安装(发布)的iso镜像 在使用以上方法安装依赖的时候xresprobe 会找不到安装地址,采用下面的方式: Package xresprobe is not in ...

  6. 来不及说什么了,Python 运维开发剁手价仅剩最后 2 天

    51reboot 运维开发又双叒叕的搞活动了—— Python 运维开发 18 天训练营课程, 剁手价1299 最后2天 上课方式:网络直播/面授(仅限北京) DAY1 - DAY4 Python3 ...

  7. Flask-sqlalchemy 语法总结

    Flask-sqlalchemy 语法总结 ** DDLdb.create_all() :创建实体表db.drop_all(): 删除表 1)插入表Db.session.add(user) #user ...

  8. centos单机安装nginx、gitlab、nexus、mysql共存

    思路就是不同系统设不同端口号,通过nginx做反向代理绑定不同域名. nginx 安装 1.安装pcre软件包(使nginx支持http rewrite模块)yum install -y pcreyu ...

  9. 701 D. As Fast As Possible

    ###链接 [http://codeforces.com/group/1EzrFFyOc0/contest/701/problem/D] ###题意 n个人,走lm,有车但没人只能坐一次,车容量为k, ...

  10. Linux内核分析——第七章 链接

    第七章——链接 1.链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载到存储器并执行. 2.链接可以执行于编译时,加载时,运行时. 7.1编译器驱动程序 1.大多数编译系 ...