LOJ#2302. 「NOI2017」整数
$n \leq 1000000$个操作:一,给$x$加上$a*2^b$;二,问$x$的某个二进制位$k$。$b,k \leq 30n$,$|a| \leq 1e9$。
30暴露了一切。。可以把30个二进制位压一位,进位用线段树找到第一个0,而退位用类似的方法找到第一个1。
但其实第$k$位只由加的总量和减的总量的0到$k$这些数位上决定。因此可以把加减分成两个数组,不用再写一个线段树里的减法。回答时查一下$0$到$k-1$中加的和减的孰大孰小,以及第$k$位是否相同,分类可得答案。
这里写的直接模拟。
//#include<iostream>
#include<cstring>
#include<cstdio>
//#include<math.h>
//#include<set>
//#include<queue>
//#include<bitset>
//#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=,f=; while ((c=getchar())<'' || c>'') (c=='-') && (f=-);
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s*f;
} //Pay attention to '-' , LL and double of qread!!!! int m,n;
#define maxn 1000011
int pos[maxn];
struct SMT
{
struct Node{int ls,rs,v; bool all0,all1,be0,be1;}a[maxn<<];
int size,n;
void up(int x)
{a[x].all0=a[a[x].ls].all0&a[a[x].rs].all0; a[x].all1=a[a[x].ls].all1&a[a[x].rs].all1;}
void build(int &x,int L,int R)
{
x=++size;
a[x].all0=; a[x].all1=a[x].be0=a[x].be1=;
if (L==R) {a[x].v=; pos[L]=x; return;}
int mid=(L+R)>>;
build(a[x].ls,L,mid); build(a[x].rs,mid+,R);
}
void clear(int N) {n=N; size=; int x; build(x,,n);} void besingle(int x,bool t)
{
a[x].all0=a[x].be0=!t;
a[x].all1=a[x].be1=t;
if (t) a[x].v=(<<)-; else a[x].v=;
}
void down(int x)
{
Node &b=a[x];
if (b.be0) {besingle(b.ls,); besingle(b.rs,); b.be0=;}
if (b.be1) {besingle(b.ls,); besingle(b.rs,); b.be1=;}
} bool Add(int x,int L,int R,int p,int v)
{
if (L==R)
{
a[x].v+=v; if (a[x].v>=(<<))
{
a[x].v^=(<<);
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return ;
}
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return ;
}
down(x);
int mid=(L+R)>>;
if (p<=mid) {bool flag=Add(a[x].ls,L,mid,p,v); up(x); return flag;}
bool flag=Add(a[x].rs,mid+,R,p,v); up(x); return flag;
}
bool f0(int x,int L,int R,int p)
{
if (L==R)
{
bool flag=;
for (int i=;i<;i++) if (((a[x].v>>i)&)==) {a[x].v|=<<i; flag=; break;}
else a[x].v^=(<<i);
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return flag;
}
down(x);
int mid=(L+R)>>;
if (L>p)
{
if (a[x].all1) {besingle(x,); return ;}
if (!f0(a[x].ls,L,mid,p)) f0(a[x].rs,mid+,R,p); up(x);
return ;
}
if (mid>p)
{
if (f0(a[x].ls,L,mid,p)) {up(x); return ;}
bool flag=f0(a[x].rs,mid+,R,p); up(x); return flag;
}
if (f0(a[x].rs,mid+,R,p)) {up(x); return ;}
up(x); return ;
}
void add(int p,int v) {p++; if (Add(,,n,p,v) && p!=n) f0(,,n,p);} bool Minus(int x,int L,int R,int p,int v)
{
if (L==R)
{
a[x].v-=v; if (a[x].v<)
{
a[x].v+=(<<);
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return ;
}
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return ;
}
down(x);
int mid=(L+R)>>;
if (p<=mid) {bool flag=Minus(a[x].ls,L,mid,p,v); up(x); return flag;}
bool flag=Minus(a[x].rs,mid+,R,p,v); up(x); return flag;
}
bool f1(int x,int L,int R,int p)
{
if (L==R)
{
bool flag=;
for (int i=;i<;i++) if (((a[x].v>>i)&)==) {a[x].v^=<<i; flag=; break;}
else a[x].v^=(<<i);
a[x].all0=(a[x].v==),a[x].all1=(a[x].v==(<<)-);
return flag;
}
down(x);
int mid=(L+R)>>;
if (L>p)
{
if (a[x].all0) {besingle(x,); return ;}
if (!f1(a[x].ls,L,mid,p)) f1(a[x].rs,mid+,R,p);
up(x); return ;
}
if (mid>p)
{
if (f1(a[x].ls,L,mid,p)) {up(x); return ;}
bool flag=f1(a[x].rs,mid+,R,p); up(x); return flag;
}
if (f1(a[x].rs,mid+,R,p)) {up(x); return ;}
up(x); return ;
}
void minus(int p,int v) {p++; if (Minus(,,n,p,v) && p!=n) f1(,,n,p);} int Query(int x,int L,int R,int p,int v)
{
if (L==R) return (a[x].v>>v)&;
down(x);
int mid=(L+R)>>;
if (p<=mid) return Query(a[x].ls,L,mid,p,v);
return Query(a[x].rs,mid+,R,p,v);
}
int query(int x) {return Query(,,n,x/+,x%);}
}t; int main()
{
m=qread(); n=qread(); n=qread(); n=qread();
n=;
t.clear(n); int op,x,y;
while (m--)
{
op=qread();
if (op==)
{
x=qread(); y=qread();
if (x>)
{
int p=y/,q=(p+)*-y;
int a=x&((<<q)-),b=x>>q; a<<=y-p*;
t.add(p,a); if (b) t.add(p+,b);
}
else
{
x=-x;
int p=y/,q=(p+)*-y;
int a=x&((<<q)-),b=x>>q; a<<=y-p*;
t.minus(p,a); if (b) t.minus(p+,b);
}
}
else
{
x=qread();
printf("%d\n",t.query(x));
}
}
return ;
}
LOJ#2302. 「NOI2017」整数的更多相关文章
- LOJ 2302 「NOI2017」整数——压位线段树
题目:https://loj.ac/problem/2302 压30位,a最多落在两个位置上,拆成两次操作. 该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 ...
- LibreOJ2302 - 「NOI2017」整数
Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...
- 「NOI2017」整数 解题报告
「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...
- loj #2305. 「NOI2017」游戏
#2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...
- loj#2305. 「NOI2017」游戏 2-sat
链接 https://loj.ac/problem/2305 https://www.luogu.org/problemnew/show/P3825 思路 3-sat神马的就不要想了,NP问题 除去x ...
- LOJ2302 「NOI2017」整数
「NOI2017」整数 题目背景 在人类智慧的山巅,有着一台字长为$1048576$位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统 ...
- LOJ 2304 「NOI2017」泳池——思路+DP+常系数线性齐次递推
题目:https://loj.ac/problem/2304 看了各种题解…… \( dp[i][j] \) 表示有 i 列.第 j 行及以下默认合法,第 j+1 行至少有一个非法格子的概率,满足最大 ...
- LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表
题目:https://loj.ac/problem/2303 想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数. 看了题解才会…… 一直想用 splay ...
- *LOJ#2306. 「NOI2017」蔬菜
$n \leq 100000$种蔬菜,每个蔬菜有:一单位价格:卖第一单位时额外价格:总量:每天腐烂量.每天能卖$m \leq 10$单位蔬菜,多次询问:前$k \leq 100000$天最多收入多少. ...
随机推荐
- javaweb基础(19)_jsp标签
一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...
- CF-1093 (2019/02/10)
CF-1093 1093A - Dice Rolling 输出x/2即可 #include<bits/stdc++.h> using namespace std; int main() { ...
- Spring Security 与 OAuth2(介绍)
https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 OAuth2(介绍) 林塬 2018.01.23 11:14* 字数 3097 阅读 ...
- mysqlfailover高可用与proxysql读写分离配置
proxysql官方推荐两种高可用方案: 1.MHA+proxysql 2.mysqlrpladmin+proxysql MySQLfailover工具包含在mysqlrpladmin工具中,所以两者 ...
- Docker 自动运行Nginx容器
Dockerfile文件如下: FROM ubuntu #基础镜像 RUN apt-get update #更新apt RUN apt-get -y install nginx #安装nginx VO ...
- Linux-缓存服务
Memcached 基本操作 解释 命令 安装 yum install memcached 启动 memcached -d -l -m -p 停止 kill pid 查看某个端口是否通:telnet ...
- vue-highlightjs的使用小结
万能的github真主,让我们强大!在vue的项目中想使用highlight.js这样的代码高亮?有人帮助我们实现了vue-highlightjs 安装 yarn add highlight.js - ...
- python数据类型之列表(list)和其常用方法
列表是python常用数据类型之一,是可变的,可由n = []创建,也可由n = list()创建,第一种方法更常用. 常用方法总结: # 创建方法 n = [] 或者 n = list() # in ...
- 2018 Multi-University Training Contest 1 Balanced Sequence(贪心)
题意: t组测试数据,每组数据有 n 个只由 '(' 和 ')' 构成的括号串. 要求把这 n 个串排序然后组成一个大的括号串,使得能够匹配的括号数最多. 如()()答案能够匹配的括号数是 4,(() ...
- 奇数结点升序偶数结点降序的单链表排序(Python实现)
题目 一个链表,奇数结点升序,偶数结点降序,要求变成一个全升序的链表. 例如:1->8->2->7->3->6->4->5,变为1->2->3-& ...