LOJ#2302 整数
解:发现这苟东西是个3千万位的二进制数......毒瘤吧。
拆位考虑,如果一个地方本来是1然后+1,就会把它和它前面连续的一段1变成0,并把第一个0变成1。
如果本来是0然后-1了,就会把它和它前面连续的一段0变成1,并把第一个1变成0。
然后发现这两个操作都可以用线段树。于是得到了一个60分算法。
然后压位,线段树每一位表示30个二进制位,可以发现之前的性质没变:如果一个地方加了后超过了(1<<30)-1,就把前面的一段1变成0,第一个0变成1。减法同理。
注意加法爆了就对(1<<30)-1取&,减法爆了就加上(1<<30),这里千万不能-1,因为是从前面借的。
有个地方坑死我了......看这里。
应该长这样...
#include <bits/stdc++.h> inline void read(int &x) {
x = ;
char c = getchar();
bool f = ;
while(c < '' || c > '') {
if(c == '-') f = ;
c = getchar();
}
while(c >= '' && c <= '') {
x = x * + c - ;
c = getchar();
}
if(f) x = (~x) + ;
return;
} const int N = , FULL = ( << ) - ; inline void out(int x) {
for(int i = ; i <= ; i++) printf("%d", (x >> i) & );
return;
} int n, tag[N], val[N], sta[N], lm;
/// tag is_same now_state inline void pushup(int o) {
if(val[o << ] == val[o << | ] && val[o << ] != -) {
val[o] = val[o << ];
}
else val[o] = -;
return;
} inline void pushdown(int o) {
if(tag[o] != -) {
tag[o << ] = tag[o << | ] = tag[o];
val[o << ] = val[o << | ] = tag[o];
sta[o << ] = sta[o << | ] = (tag[o] ? FULL : );
tag[o] = -;
}
return;
} void changeAdd(int l, int r, int o) {
if(l == r) {
for(int i = ; i < ; i++) {
if(((sta[o] >> i) & ) == ) {
sta[o] |= ( << i);
break;
}
else {
sta[o] &= ~( << i);
}
}
if(sta[o] == FULL) val[o] = ;
else if(sta[o] == ) val[o] = ;
else val[o] = -;
return;
}
int mid = (l + r) >> ;
pushdown(o);
if(val[o << ] != ) {
changeAdd(l, mid, o << );
}
else {
changeAdd(mid + , r, o << | );
sta[o << ] = val[o << ] = tag[o << ] = ;
}
pushup(o);
return;
} void changeDel(int l, int r, int o) {
if(l == r) {
for(int i = ; i < ; i++) {
if((sta[o] >> i) & ) {
sta[o] &= ~( << i);
break;
}
else {
sta[o] |= ( << i);
}
}
if(sta[o] == FULL) val[o] = ;
else if(sta[o] == ) val[o] = ;
else val[o] = -;
return;
}
int mid = (l + r) >> ;
pushdown(o);
if(val[o << ] != ) {
changeDel(l, mid, o << );
}
else {
changeDel(mid + , r, o << | );
val[o << ] = tag[o << ] = ;
sta[o << ] = FULL;
}
pushup(o);
return;
} int add(int p, int v, int l, int r, int o) {
if(l == r) {
sta[o] += v;
int t = ;
if(sta[o] > FULL) {
sta[o] &= FULL;
t = ;
}
if(sta[o] == FULL) val[o] = ;
else if(sta[o] == ) val[o] = ;
else val[o] = -;
return t;
}
int mid = (l + r) >> ;
pushdown(o);
int t;
if(p <= mid) {
t = add(p, v, l, mid, o << );
pushup(o);
if(t && val[o << | ] != ) {
changeAdd(mid + , r, o << | );
pushup(o);
return ;
}
else if(t) {
tag[o << | ] = val[o << | ] = sta[o << | ] = ;
pushup(o);
return ;
}
else return ;
}
else {
t = add(p, v, mid + , r, o << | );
pushup(o);
return t;
}
return ;
} int del(int p, int v, int l, int r, int o) {
if(l == r) {
sta[o] -= v;
int t = ;
if(sta[o] < ) {
sta[o] += FULL + ;
t = ;
}
if(sta[o] == FULL) val[o] = ;
else if(sta[o] == ) val[o] = ;
else val[o] = -;
return t;
}
int mid = (l + r) >> ;
pushdown(o);
int t;
if(p <= mid) {
t = del(p, v, l, mid, o << );
pushup(o);
if(t && val[o << | ] != ) {
changeDel(mid + , r, o << | );
pushup(o);
return ;
}
else if(t) {
tag[o << | ] = val[o << | ] = ;
sta[o << | ] = FULL;
pushup(o);
return ;
}
else return ;
}
else {
t = del(p, v, mid + , r, o << | );
pushup(o);
return t;
}
return ;
} inline void Add(int p, int x) { /// node p add x
if(!x) return;
add(p, x, , lm, );
return;
} inline void Del(int p, int x) {
if(!x) return;
del(p, x, , lm, );
return;
} int ask(int p, int l, int r, int o) {
if(l == r) {
p -= (l - ) * ;
return (sta[o] >> p) & ;
}
int mid = (l + r) >> ;
pushdown(o);
if(p <= mid * - ) return ask(p, l, mid, o << );
else return ask(p, mid + , r, o << | );
} void out(int l, int r, int o) {
if(l == r) {
return;
}
int mid = (l + r) >> ;
pushdown(o);
out(l, mid, o << );
out(mid + , r, o << | );
return;
} int main() {
int t1, t2, t3;
memset(tag, -, sizeof(tag));
scanf("%d%d%d%d", &n, &t1, &t2, &t3);
lm = std::max(n + , );
for(int i = , f, x, y; i <= n; i++) {
scanf("%d%d", &f, &x);
if(f == ) {
printf("%d\n", ask(x, , lm, ));
}
else {
scanf("%d", &y);
int t, fd = ;
if(x < ) {
x = -x;
fd = ;
}
if(!fd) { /// add
t = (x << (y % )) & FULL;
Add(y / + , t);
t = x >> ( - (y % ));
Add(y / + , t);
}
else { /// dec
t = (x << (y % )) & FULL;
Del(y / + , t);
t = x >> ( - (y % ));
Del(y / + , t);
}
}
}
return ;
}
AC代码
LOJ#2302 整数的更多相关文章
- LOJ 2302 「NOI2017」整数——压位线段树
题目:https://loj.ac/problem/2302 压30位,a最多落在两个位置上,拆成两次操作. 该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 ...
- LOJ#2302. 「NOI2017」整数
$n \leq 1000000$个操作:一,给$x$加上$a*2^b$:二,问$x$的某个二进制位$k$.$b,k \leq 30n$,$|a| \leq 1e9$. 30暴露了一切..可以把30个二 ...
- NOI 2017 整数(线段树)
题意 https://loj.ac/problem/2302 思路 拆分成每个二进制位的加减来考虑,维护那个整数的二进制位.不难发现,进位就是找右边第一个 \(0\) 的位置,并将其赋值为 \(1\) ...
- BZOJ 2302: [HAOI2011]Problem c( dp )
dp(i, j)表示从i~N中为j个人选定的方案数, 状态转移就考虑选多少人为i编号, 然后从i+1的方案数算过来就可以了. 时间复杂度O(TN^2) ------------------------ ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #2331. 「清华集训 2017」某位歌姬的故事
Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
随机推荐
- ArrayList的扩容机制
一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...
- CentOS7学习
1.为什么学linux? linux开源免费,系统稳定,多用户的操作系统. linux有许多版本,各个版本之间的不同点大概分三种? > 内核不同 > 集成不同的应用 > 定制不同的图 ...
- 引入kaptcha实现验证码验证
1.导入jar包, 可以选择去 https://mvnrepository.com 里面搜索,也可以直接复制下面的代码 2.复制到maven配置文件pom.xml中并保存 <dependency ...
- JQ remove()方法实现似收货地址逐一删除的效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 库存盘点打印功能生成PDF速度太慢使用页面缓存
一.业务需求 二.产品设计 三.UI设计 四.程序设计 1.使用behavior配置页面缓存 class WmsCheckController extends Controller { /** * @ ...
- 《Tensorflow从入门到精通》
第一 开发环境搭建 1. tensorflow的环境搭建 windows下安装cpu版tensorflow: pip install tensorflow 在ubuntu上安装gpu版tensorfl ...
- 多线程的实现方式01 Thread
/* * 多线程 有三种实现方式 * 其一 Thread * * 写一个类 * * 1.让他继承 Thread * 2.重写thread中的run方法 * 3.创建子类对象就是在 创建线程! * 3. ...
- github上传时出现error: src refspec master does not match any解决办法22
1 error:src refspec master does not match any这个问题,我之前也遇到过,这次又遇到了只是时间间隔比较长了,为了防止以后再遇到类似问题,还是把这个方法简单记录 ...
- WebAPI MVC Change Identity Default Table
看过之前的文章小伙伴们应该已经明白了,当我们新建一个带有身份验证的模板时,会自带Identity Server,并且它的表名和字段名也都是默认的. 那么该如何修改它,并让EF知道呢?不废话,直接上代码 ...
- CSS3 flexbox 布局 ---- flex 容器属性介绍
flexbox布局是CSS3中新增的属性,它可以很轻松地帮我们解决掉一些常见的布局问题,比如导航栏. 我们用普通的方法写导航栏,通常会在ul, li 结构写好后,让li 元素左浮动,然后再给ul 清浮 ...