[bzoj4942] [洛谷P3822] [NOI2017] 整数
题目链接##
https://www.luogu.org/problemnew/show/P3822
想法##
这个啊,就是线段树哇
最初的想法是每位一个节点,然后进位、退位找这一位前面第一个0或第一个1,然后把中间一段修改了即可
但是每位一个节点太浪费了,会超时,故可以压位,30位一个节点
要找每个点前面第一个0或1的话,可以记录一下每个区间里是否全0或全1,不停地维护
反正基本思路就是这样,但是代码真心挺恶心的,调了一天呢!NOI题真是毒瘤!
(初三一模前两天调这个代码,酸爽啊……qwq)
代码##
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int read(){
char ch=getchar();
int ret=0,f=1;
while(!isdigit(ch) && ch!='-') ch=getchar();
if(ch=='-') f=-1,ch=getchar();
while(isdigit(ch)) ret=ret*10+ch-'0',ch=getchar();
return f*ret;
}
typedef long long ll;
const int N = 1000005;
const int MAX = 1000000;
const int FULL = (1<<30)-1;
struct node{
int v,flag,lazy,id;
node *ch[2],*pa;
}pool[N*4],*root;
int cnt;
void build(node *p,int l,int r){
p->v=p->flag=0; p->lazy=-1;
if(l==r) { p->id=l; return; }
int mid=(l+r)>>1;
build(p->ch[0]=&pool[++cnt],l,mid);
build(p->ch[1]=&pool[++cnt],mid+1,r);
p->ch[0]->pa=p; p->ch[1]->pa=p;
}
void update(node *p){
if(!p->ch[0]){ //single
if(p->v==FULL) p->flag=1;
else if(p->v==0) p->flag=0;
else p->flag=-1;
}
else if(p->ch[0]->flag==p->ch[1]->flag) p->flag=p->ch[0]->flag;
else p->flag=-1;
}
void up(node *p){
if(!p) return;
update(p); up(p->pa);
}
void pushdown(node *p){
if(p->lazy==-1) return;
if(!p->ch[0]) return;
p->ch[0]->lazy=p->lazy; p->ch[0]->flag=p->lazy;
if(!p->ch[0]->ch[0]) p->ch[0]->v=p->lazy ? FULL : 0;
p->ch[1]->lazy=p->lazy; p->ch[1]->flag=p->lazy;
if(!p->ch[1]->ch[0]) p->ch[1]->v=p->lazy ? FULL : 0;
p->lazy=-1;
}
node *get_node(node *p,int l,int r,int c){
if(l==r) return p;
pushdown(p);
int mid=(l+r)>>1;
if(c<=mid) return get_node(p->ch[0],l,mid,c);
return get_node(p->ch[1],mid+1,r,c);
}
void fix(node *p,int l,int r,int c,int f){
if(l==r){
if(f==0) p->v++;
else p->v--;
update(p);
return;
}
pushdown(p);
int mid=(l+r)>>1;
if(c<=mid) fix(p->ch[0],l,mid,c,f);
else fix(p->ch[1],mid+1,r,c,f);
update(p);
}
void change(node *p,int l,int r,int L,int R,int f){
if(l==L && r==R){
p->lazy=p->flag=f;
if(l==r) p->v= f ? FULL : 0;
return;
}
pushdown(p);
int mid=(l+r)>>1;
if(R<=mid) change(p->ch[0],l,mid,L,R,f);
else if(L>mid) change(p->ch[1],mid+1,r,L,R,f);
else{
change(p->ch[0],l,mid,L,mid,f);
change(p->ch[1],mid+1,r,mid+1,R,f);
}
update(p);
}
int find(node *p,int c,int f){ //f=1: 011111 f=0:100000
if(p->flag!=f){
if(!p->ch[0]) return p->id;
if(c==-1){
pushdown(p);
if(p->ch[0]->flag!=f) return find(p->ch[0],-1,f);
else return find(p->ch[1],-1,f);
}
if(c==0 && p->ch[1] && p->ch[1]->flag!=f) return find(p->ch[1],-1,f);
return find(p->pa,p==p->pa->ch[1],f);
}
return find(p->pa,p==p->pa->ch[1],f);
}
void add(int a,int x){
int ty=a/30+1,y=x*(1<<(a-(ty-1)*30));
node *p=get_node(root,1,MAX,ty);
if(p->v+y<=FULL) { p->v+=y; up(p); return; }
p->v=p->v+y-FULL-1; up(p);
node *q=get_node(root,1,MAX,ty+1);
int v=find(q,0,1);
if(v==ty+1) fix(root,1,MAX,ty+1,0);
else change(root,1,MAX,ty+1,v-1,0),fix(root,1,MAX,v,0);
}
void del(int a,int x){
int ty=a/30+1,y=x*(1<<(a-(ty-1)*30));
node *p=get_node(root,1,MAX,ty);
if(p->v-y>=0) { p->v-=y; up(p); return; }
p->v=p->v-y+FULL+1; up(p);
node *q=get_node(root,1,MAX,ty+1);
int v=find(q,0,0);
if(v==ty+1) fix(root,1,MAX,ty+1,1);
else change(root,1,MAX,ty+1,v-1,1),fix(root,1,MAX,v,1);
}
void Add(int a,int x){
int ty=a/30+1;
ll y=x*(1ll<<(a-(ty-1)*30));
if(y<=1ll*FULL) add(a,x);
else add((ty-1)*30,(int)(y%(FULL+1))),add(ty*30,(int)(y/(FULL+1)));
}
void Del(int a,int x){
int ty=a/30+1;
ll y=x*(1ll<<(a-(ty-1)*30));
if(y<=1ll*FULL) del(a,x);
else del((ty-1)*30,(int)(y%(FULL+1))),del(ty*30,(int)(y/(FULL+1)));
}
int main()
{
int n,opt,a,b;
n=read();read();read();read();
root=&pool[++cnt];
build(root,1,MAX);
for(int i=0;i<n;i++){
opt=read();
if(opt==1){
a=read(); b=read();
if(a>0) Add(b,a);
else if(a<0) Del(b,-a);
}
else{
a=read();
node *p=get_node(root,1,MAX,a/30+1);
printf("%d\n",(p->v&(1<<(a-(a/30)*30)))!=0 ? 1 : 0);
}
}
return 0;
}
[bzoj4942] [洛谷P3822] [NOI2017] 整数的更多相关文章
- 洛谷3822 [NOI2017] 整数 【线段树】【位运算】
题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...
- 洛谷3825 [NOI2017]游戏 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】
UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...
- 洛谷——P1107 最大整数
P1107 最大整数 题目描述 设有n个正整数 (n<=20), 将它们连接成一排, 组成一个最大的多位整数. 例如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 3433 ...
- codevs——T1860 最大数||洛谷——P1107 最大整数
http://codevs.cn/problem/1860/ || https://www.luogu.org/problem/show?pid=1107#sub 题目描述 Description 设 ...
- 洛谷——P1151 子数整数
P1151 子数整数 题目描述 对于一个五位数a1a2a3a4a5,可将其拆分为三个子数: sub1=a1a2a3 sub2=a2a3a4 sub3=a3a4a5 例如,五位数20207可以拆分成 s ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- 洛谷P3825 [NOI2017]游戏(2-SAT)
传送门 果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕…… 先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i' ...
随机推荐
- 超容易理解的call()、apply()、bind()的区别
call().apply().bind()是用来改变this的指向的. 一 举个例子 一个叫喵喵的猫喜欢吃鱼,一个叫汪汪的小狗喜欢啃骨头,用代码实现如下: 有一天,小狗汪汪和喵喵共进午餐的时候,汪汪说 ...
- poj2826 An Easy Problem?!(计算几何)
传送门 •题意 两根木块组成一个槽,给定两个木块的两个端点 雨水竖直下落,问槽里能装多少雨水, •思路 找不能收集到雨水的情况 我们令线段较高的点为s点,较低的点为e点 ①两条木块没有交点 ②平行或重 ...
- Linux网络文件共享服务之FTP
一.FTP介绍 ftp(File Transfer Protocol)是早期的三个应用级协议之一,基于C/S结构,双通道协议,数据和命令连接,数据传输格式默认是二进制,当然也支持文件方式传输.默认情况 ...
- Rancher2.x部署K8s
1.安装Docker [root@localhost ~]# docker -v Docker version , build 774a1f4 2.使用Docker运行Rancher : stable ...
- axure公式的使用和局部变量简介
什么时候有公式?当前面是值的时候后面都可以用公式 公式怎么用?1.公式里直接写入字符串 2.变量([变量])加上字符串 3.[[]]里面运算 外面字符串 两个中括号里的变量就可以计算或者显示默认值而不 ...
- [梁山好汉说IT] 容器概念在北宋社会的应用
[梁山好汉说IT] 容器概念在北宋社会的应用 0x00 摘要 如何对没有软件开发经验的人解释容器? 集装箱真的能够完美解释容器嘛? 除了集装箱还有其他常见实体能够解释容器嘛? 我找到了一个能够 和集装 ...
- java的package和import机制
在说package.import机制前我们先来了解下java的CLASSPATH. CLASSPATH顾名思义就是class的路径,当我们在系统中运行某个java程序时,它就会告诉系统在这些地方寻找这 ...
- knn识别简单验证码
参考 https://www.biaodianfu.com/knn-captcha-recognition.html 内容大致一样,只是根据自己的想法加入了一些改动 KNN(k近邻算法) 算法原理请看 ...
- 15 道 Spring Boot 高频面试题,看完直接当面霸【入门实用】
前言 本文转自松哥(网名:江南一点雨)的一篇实用入门文章,写的挺好的,希望对各位有所帮助. 什么是面霸?就是在面试中,神挡杀神佛挡杀佛,见招拆招,面到面试官自惭形秽自叹不如!松哥希望本文能成为你面霸路 ...
- Linux 学习笔记 5 文件的下载、压缩、解压、初步认识yum
写在前面 上节我们通过简单的几组命令,已经完全的实现了文件的移动.删除.更名.以及复制,我们最常用的基本玩法,本节将带着大家学习压缩.解压的相关步骤. Linux 学习笔记 4 创建.复制.移动.文件 ...