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$天最多收入多少. ...
随机推荐
- python-判断alter是否存在
from selenium import webdriver import time from selenium.webdriver.support.ui import WebDriverWait f ...
- Java--equals和 == 的比较和equals()、HashCode()的重写
一. equals和 == 的比较 1.== 运算符 ① == 如果比较的是基本数据类型,则比较的是值. ② == 如果比较的是引用数据类型,则比较的是地址值. 2.equals ①它属于java.l ...
- 如何用纯 CSS 创作一个文本淡入淡出的 loader 动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ERwpeG 可交互视频 ...
- 不使用脚手架的 vue 应用
工作中的项目不止有页面繁多的模块化项目,还会只有一两个页面的类似于填写信息参与活动的活动页.这个时候,就可以回归以前的三剑客模式,在 index.html 里引用 vue.js 进行开发. 关键点: ...
- Python 变量作用域 LEGB (上)—— Local,Global,Builtin
Python 变量作用域的规则是 LEGB LEGB含义解释:L —— Local(function):函数内的名字空间E —— Enclosing function locals:外部嵌套函数的名字 ...
- Centos7 开机显示 ERST: Failed to get Error Log Address Range” 导致无法开机解决方法
开机显示 ERST: Failed to get Error Log Address Range” 导致无法开机,也无法重新安装系统,解决方法:开机进入BIOS , 关闭ACPI选项即可正常开机
- 修改const变量
看下面的一段代码 ; int * j=(int*)(&i); // 运行正确,j确为i的地址,但 int *j=&i; 编译错误 *j=; //确实改变了i的值 printf(&quo ...
- I love you
while(true) { printf("I love you"); } 字母解析 I-Inject--投入 投入,这个投入有很多概念,有对自己所爱的人,投入自己所有的感情,让你 ...
- 使用SpringMVC参数传递时,解决get请求时中文乱码的问题
问题描述: 使用SpringMVC参数传递时, 遇到get请求中文信息时,页面应答会显示中文乱码. 解决办法: 一, 我们需要把request.getParameter(“参数名”)获取到的字符串先 ...
- 【LeetCode】Balanced Binary Tree(平衡二叉树)
这道题是LeetCode里的第110道题. 题目要求: 给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. ...