题目链接##

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. 【16.50%】【CF 44G】Shooting Gallery

    time limit per test 5 seconds memory limit per test 256 megabytes input standard input output standa ...

  2. javascript基础之数组一

    <script type="text/javascript"> //求数组中最大的数 var arr=[123,456,789,657,432,564]; var ar ...

  3. C# 字典 Dictionary 的 TryGetValue 与先判断 ContainsKey 然后 Get 的性能对比

    本文使用 benchmarkdotnet 测试字典的性能,在使用字典获取一个可能存在的值的时候可以使用两个不同的写法,于是本文分析两个写法的性能. 判断值存在,如果值存在就获取值,可以使用下面两个不同 ...

  4. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  5. HDU 6444 Neko's loop(单调队列)

    Neko has a loop of size nn. The loop has a happy value aiai on the i−th(0≤i≤n−1)i−th(0≤i≤n−1) grid.  ...

  6. 红米K20 Pro 传感器失效解决方案

    最近把Redmi K20 Pro升级到了安卓Q,用了几天,不好用,总是提示屏幕前方有遮挡,于是刷回了安卓9,但是发现重力感应传感器失效了,屏幕不会随这方向转,导航的时候看起来很难受. 网上查了一下,要 ...

  7. linux 如何查找命令的路径(which搜索系统命令,whichis搜索文件)

    http://hi.baidu.com/longredhao/item/911356ea2d8bed3687d9deed linux 下,我们常使用 cd ,grep,vi 等命令,有时候我们要查到这 ...

  8. 一篇文章带你了解 ZooKeeper 架构

    上一篇文章,我们讲解了 ZooKeeper 入门知识,这篇文章主要讲解下 ZooKeeper 的架构,理解 ZooKeeper 的架构可以帮助我们更好地设计协同服务. 首先我们来看下 ZooKeepe ...

  9. The sixth day of Crawler learning

    爬取我爱竞赛网的大量数据 首先获取每一种比赛信息的分类链接 def get_type_url(url):    web_data = requests.get(web_url)    soup = B ...

  10. 天猫SSM项目学习记录(一)----第一个相对完整的SSM项目

    来源:  http://how2j.cn/k/tmall_ssm/tmall_ssm-1516/1516.html?p=78908 目的:记录一个相对完整的SSM项目模板 1.工具:idea2018商 ...