NOI2017 整数

题意:

​ 让你实现两个操作:

  • 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数
  • 2 \(k\):询问 \(x\)在用二进制表示时,位权为\(2 ^ k\)的位的值(即这一位上的\(1\)代表\(2 ^ k\))

​ 一百万次操作,$ |a| \leq 10^9,b,k\leq30n$。

题解:

​ 线段树+压位,30位一位,没了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define of(i,l,r) for(int i=l;i>=r;i--)
#define fe(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
inline void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[20];
sprintf(str,"in%s.txt",s);
freopen(str,"r",stdin);
// sprintf(str,"out%s.txt",s);
// freopen(str,"w",stdout);
#endif
}
inline int rd()
{
static int x,f;
x=0;f=1;
char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return f>0?x:-x;
}
const int N=1000010,n=N-2,B=30,S=(1<<B)-1;
int m,rt; namespace Seg{
#define lson tr[o].ls,l,mid
#define rson tr[o].rs,mid+1,r
#define qlson lson,L,min(mid,R)
#define qrson rson,max(mid+1,L),R
struct tree{
int ls,rs,val0,val1,tag;//1 or 0 and
tree(){ls=rs=val0=val1=0;tag=-1;}
}tr[N<<1];int cnt=0; void build(int &o,int l,int r)
{
o=++cnt;
if(l==r)return;
int mid=(l+r)>>1;
build(lson);
build(rson);
} inline void pushup(int o)
{
tr[o].val1=tr[tr[o].ls].val1|tr[tr[o].rs].val1;
tr[o].val0=tr[tr[o].ls].val0&tr[tr[o].rs].val0;
}
inline void pushdown(int o)
{
if(!~tr[o].tag)return;
int ls=tr[o].ls,rs=tr[o].rs;
tr[ls].val0=tr[ls].val1=tr[ls].tag=tr[o].tag;
tr[rs].val0=tr[rs].val1=tr[rs].tag=tr[o].tag;
tr[o].tag=-1;
} int find1(int o,int l,int r,int x)
{
if(tr[o].val0==S)return -1;
if(l==r)return l;
pushdown(o);
int mid=(l+r)>>1,res=-1;
if(x<=mid)res=find1(lson,x);
if(~res)return res;
return find1(rson,x);
}
int find0(int o,int l,int r,int x)
{
if(!tr[o].val1)return -1;
if(l==r)return l;
pushdown(o);
int mid=(l+r)>>1,res=-1;
if(x<=mid)res=find0(lson,x);
if(~res)return res;
return find0(rson,x);
} void updata(int o,int l,int r,int x,int d)
{
if(l==r)return tr[o].val0+=d,tr[o].val1+=d,void();
pushdown(o);
int mid=(l+r)>>1;
if(x<=mid)updata(lson,x,d);
else updata(rson,x,d);
pushup(o);
}
void paint(int o,int l,int r,int L,int R,int d)
{
if(l==L&&r==R)return tr[o].tag=tr[o].val0=tr[o].val1=d,void();
pushdown(o);
int mid=(l+r)>>1;
if(L<=mid)paint(qlson,d);
if(R>mid)paint(qrson,d);
pushup(o);
} int query(int o,int l,int r,int x)
{
if(l==r)return tr[o].val0;
pushdown(o);
int mid=(l+r)>>1;
if(x<=mid)return query(lson,x);
return query(rson,x);
} } inline void inc(int p,int x)
{
static int res,y;
// printf("%d %d\n",p,x);
res=Seg::query(rt,0,n,p);
if(res+x<=S)return Seg::updata(rt,0,n,p,x);
Seg::updata(rt,0,n,p,x-S-1);
y=Seg::find1(rt,0,n,p+1);
// printf("%d\n",y);
if(y>p+1)Seg::paint(rt,0,n,p+1,y-1,0);
Seg::updata(rt,0,n,y,1);
}
inline void dec(int p,int x)
{
static int res,y;
// printf("%d %d\n",p,x);
res=Seg::query(rt,0,n,p);
if(res-x>=0)return Seg::updata(rt,0,n,p,-x);
Seg::updata(rt,0,n,p,S-x+1);
y=Seg::find0(rt,0,n,p+1);
// printf("%d\n",y);
if(y>p+1)Seg::paint(rt,0,n,p+1,y-1,S);
Seg::updata(rt,0,n,y,-1);
} inline void gao1()
{
static int x,y,p;
x=rd();y=rd();p=y/B;
if(x>0){
inc(p,(x<<(y-p*B))&S);
inc(p+1,x>>(B-y+p*B));
}
else{
x=-x;
dec(p,(x<<(y-p*B))&S);
dec(p+1,x>>(B-y+p*B));
}
}
inline void gao2()
{
static int x,p,res;
x=rd();p=x/B;
res=Seg::query(rt,0,n,p);
if(res&(1<<(x-p*B)))puts("1");
else puts("0");
} int main()
{
m=rd();rd();rd();rd();
Seg::build(rt,0,n);
while(m--){
int ty=rd();
if(ty==1)gao1();
else gao2();
}
return 0;
}

NOI2017整数的更多相关文章

  1. [NOI2017]整数

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

  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. 【BZOJ4942】[NOI2017]整数(分块)

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

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

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

  6. [BZOJ4942] [NOI2017]整数

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

  7. BZOJ.4942.[NOI2017]整数(分块)

    BZOJ 洛谷 UOJ 可能是退役之前最后一个BZOJ rank1了? 参考这里. 如果没有减法,对一个二进制数暴力进位,均摊复杂度是\(O(1)\)的(要进\(O(n)\)次位就至少需要\(O(n) ...

  8. 洛谷3822 [NOI2017] 整数 【线段树】【位运算】

    题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...

  9. BZOJ4942 NOI2017整数(线段树)

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

随机推荐

  1. WebRTC Native APIs

    WebRTC Native APIs The WebRTC Native APIs implementation is based on W3C’s WebRTC 1.0: Real-time Com ...

  2. 在windows下如何新建爬虫虚拟环境和进行scrapy安装

    Scrapy是Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改.Sc ...

  3. NodeJS学习笔记 (30)定时器-timers

    https://github.com/chyingp/nodejs-learning-guide

  4. 记intel杯比赛中各种bug与debug【其四】:基于长短时记忆神经网络的中文分词的实现

    (标题长一点就能让外行人感觉到高大上) 直接切入主题好了,这个比赛还必须一个神经网络才可以 所以我们结合主题,打算写一个神经网络的中文分词 这里主要写一下数据的收集和处理,网络的设计,代码的编写和模型 ...

  5. PHP实现几种经典算法详解

    前言 在编写JavaScript代码的时候存在一些对于数组的方法,可能涉及的页面会很多,然后每次去写一堆代码.长期下去代码会特别的繁多,是时候进行一波封装了,话不多说开始书写优美的代码 代码已上传gi ...

  6. python语法学习笔记

    函数的参数   定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来 ...

  7. GenIcam标准介绍

    GenICam TM的目标是为各种相机和设备提供通用编程接口.无论他们使用什么接口技术(GigE Vision,USB3 Vision,CoaXPress,Camera Link HS,Camera ...

  8. [转] C# HttpWebRequest 绝技

    c# HttpWebRequest与HttpWebResponse绝技    阅读原文 如果你想做一些,抓取,或者是自动获取的功能,那么就跟我一起来学习一下Http请求吧.本文章会对Http请求时的G ...

  9. Struts(21)OGNL具体解释

    Struts2 中内置了OGNL表达式的支持,使得Struts2的具有比Struts1更为强大的数据訪问的功能.本文主要解说OGNL的用法.并不会去解说一些原理性的东西.想要了解的朋友能够自己去查阅相 ...

  10. LVDS原理及设计指南

    LVDS是一种低摆幅的差分信号技术,它使得信号能在差分PCB 线对或平衡电缆上以 几百Mbps的速率传输,其低压幅和低电流驱动输出实现了低噪声和低功耗.       IEEE 在两个标准中对LVDS ...