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把她最喜欢的一个二叉树模型挂在了墙上, ...
随机推荐
- css3特殊图形(气泡)
一.气泡 效果: body{ background: #dd5e9d; height: 100%; } .paopao { position: absolute; width: 200px; heig ...
- (三)类数组对象 NamedNodeMap简单介绍
Ele.attrbutes将返回一个NamedNodeMap对象,即NamedNodeMap存储的是元素的“特性Attribute”集合.而集合中的每一个元素,都是Attr类型的对象. html: & ...
- cookie,localStorage和sessionStorage区别
三者的异同 特性 Cookie localStorage sessionStorage 数据的生命期 一般由服务器生成,可设置失效时间.如果在浏览器端生成Cookie,默认是关闭浏览器后失效 除非被清 ...
- Hbase 架构体系
有2个节点进程,一个是master,另一是regionserver.
- 移动端Web界面滚动touch事件
解决办法一: elem.addEventListener( 'touchstart', fn, { passive: false } ); 解决办法二: * { touch-action: pan-y ...
- Netty ByteBuf和Nio ByteBuffer
参考https://blog.csdn.net/jeffleo/article/details/69230112 一.简介 Netty中引入了ByteBuf,它相对于ByteBuffer来说,带来了很 ...
- 和docket的第一次亲密接触
很久很久以前,第一次听说docker时,感觉很高大上,同时自我感觉会很难.所以一直没有详细了解.前一段时间偶尔看到关于docker的详细介绍,于是乎来了兴趣.自已折腾了一下,发现不是想象中的那么难. ...
- RabbitMQ在Ubuntu 16.04下的安装与配置
安装执行如下命令: echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d ...
- 洛谷 P1112 波浪数
题目描述 波浪数是在一对数字之间交替转换的数,如 121212112121211212121 ,双重波浪数则是指在两种进制下都是波浪数的数,如十进制数 191919191919191919 是一个十进 ...
- python 脚本之 获取远程主机的hostname
import sys, socket try: result = socket.gethostbyaddr("查询的IP") #查询完后获得一个元组 print (result) ...