题目链接##

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] 整数的更多相关文章

  1. 洛谷3822 [NOI2017] 整数 【线段树】【位运算】

    题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...

  2. 洛谷3825 [NOI2017]游戏 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8146041.html 题目传送门 - 洛谷3825 题解 我们考虑到地图中x的个数很少,最多只有8个. 所以我们 ...

  3. 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】

    题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...

  4. 洛谷 P3825 [NOI2017]游戏 【2-SAT+状压】

    UOJ和洛谷上能A,bzoj 8ms即WA,现在也不是知道为啥--因为我太弱了 先看数据范围发现d非常小,自然想到了状压. 所以先假装都是只能跑两种车的,这显然就是个2-SAT问题了:对于x场没有hx ...

  5. 洛谷——P1107 最大整数

    P1107 最大整数 题目描述 设有n个正整数 (n<=20), 将它们连接成一排, 组成一个最大的多位整数. 例如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 3433 ...

  6. codevs——T1860 最大数||洛谷——P1107 最大整数

    http://codevs.cn/problem/1860/ || https://www.luogu.org/problem/show?pid=1107#sub 题目描述 Description 设 ...

  7. 洛谷——P1151 子数整数

    P1151 子数整数 题目描述 对于一个五位数a1a2a3a4a5,可将其拆分为三个子数: sub1=a1a2a3 sub2=a2a3a4 sub3=a3a4a5 例如,五位数20207可以拆分成 s ...

  8. 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】

    题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...

  9. 洛谷P3825 [NOI2017]游戏(2-SAT)

    传送门 果然图论的题永远建图最麻烦……看着题解代码的建图过程真的很珂怕…… 先不考虑地图$x$,那么每一个地图都只能用两种赛车,于是我们可以用2-SAT来搞,用$i$表示这个地图能用的第一辆车,$i' ...

随机推荐

  1. The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛

    B.super_log (欧拉降幂) •题意 定一个一个运算log*,迭代表达式为 给定一个a,b计算直到迭代结果>=b时,最小的x,输出对m取余后的值 •思路 $log*_{a}(1)=1+l ...

  2. Keras文本预处理

    学习了Keras文档里的文本预处理部分,参考网上代码写了个例子 import keras.preprocessing.text as T from keras.preprocessing.text i ...

  3. Python 实现栈与队列

    #基于Python2.7 #基于顺序表实现 #发现用Python写题时,没有像写C++时方便的STL可用,不过查阅资料之后发现用class实现也很简洁,不过效率应该不是很高 Python实现栈并使用: ...

  4. python类方法、类属性和静态方法

    class Game(object): #类属性 num = 0 #实例方法 def __init__(self): #实例属性 self.name = "laowang" #类方 ...

  5. c++ 知道旋转前后矩阵向量值 求旋转矩阵c++/c#代码 知道两个向量求他们的旋转矩阵

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12115244.html 知道旋转前后矩阵向量值 如何去求旋转矩阵R 的c++/c#代码??? ...

  6. 洛谷P1248 加工生产调度 贪心

    正解:贪心 解题报告: 传送门$QwQ$ $umm$直接看可能比较难想,可以先考虑另一个题? 有$n$个小怪,每打一只小怪会扣$a_i$的血,打完之后会回升$b_i$的血,问至少要多少血量才能使全程血 ...

  7. mysql5.7 数据库自动备份脚本

    新建备份目录 mkdir /backups mkdir /backups/mysql 新建存放备份脚本目录 mkdir /data/scripts 备份脚本: mysql_backup.sh ==== ...

  8. openLayers中WMTS结合GeoServer呈现瓦片地图

    首先看openlayers官网中wmts模块,https://openlayers.org/en/latest/apidoc/module-ol_source_WMTS-WMTS.html,里面的参数 ...

  9. Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)

    这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...

  10. 1045 快速排序 (25 分)C语言

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的 N 个互不相同的正整数的排列,请问 ...