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把她最喜欢的一个二叉树模型挂在了墙上, ...
随机推荐
- C# 中那些常用的工具类(Utility Class)(二)
今天按照这一年来经常用到的那些静态的工具类再来做一次总结,这些小的工具来可以作为自己学习的很好的例子,通过总结这些东西,能够很大程度上梳理自己的知识体系,当然这个是经常用到的,接下来就一个个去分析这些 ...
- chrome中 GET /undefined 404
Chrome中调试网站,会出现 这是由 crxMouse Chrome™ 手势 引起的,关闭即可
- LodopJS文档式模版的加载和赋值
Lodop模版有两种方法,一种是传统的JS语句,可以用JS方法里的eval来执行,一种是文档式模版,是特殊格式的base64码,此篇博文介绍文档式模版的加载,文档式模版的生成以及传统JS模版的生成加载 ...
- python----函数初识
一,什么是函数? 现在有这么个情况:python中的len方法不让用了,你怎么办? 来测试一下‘hello word’ 的长度: s1 = "hello world" length ...
- 查询SQLSERVER中系统所有表
SQL 查询所有表名: SELECT NAME FROM SYSOBJECTS WHERE TYPE='U' SELECT * FROM INFORMATION_SCHEMA.TABLES 查询表的所 ...
- LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】
题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...
- Matplotlib学习---用matplotlib画阶梯图(step plot)
这里利用Nathan Yau所著的<鲜活的数据:数据可视化指南>一书中的数据,学习画图. 数据地址:http://datasets.flowingdata.com/us-postage.c ...
- GCD HDU - 1695 (欧拉 + 容斥)
GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- Eclipse中项目Project Explorer视图与Package Explorer视图
Package Explorer视图: Project Explorer视图 两种视图的切换:
- Square(斯特林反演)
题意 给出一个 \(n × m\) 大小的矩形,每个位置可以填上 \([1, c]\) 中的任意一个数,要求填好后任意两行互不等价且任意两列互不等价,两行或两列等价当且仅当对应位置完全相同,求方案数 ...