【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
【BZOJ4942】[Noi2017]整数
题目描述去uoj
题解:如果只有加法,那么直接暴力即可。。。(因为1的数量最多nlogn个)
先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依次更新这log位,如果最高位依然有进位,那么找到最高位后面的第一个0,将中间的所有1变成0,那个0变成1。这个显然要用到线段树,但是复杂度是nlog2n的,肯定过不去。
于是我在考场上yy了一下,这log位是连续的,我们每次都要花费log的时间去修改一个岂不是很浪费?我们可以先在线段树上找到这段区间,然后在线段树上dfs下去,这样,时间复杂度就变成O(logn+那段区间在线段树上的大小)。因为一颗正常的线段树的大小就是4*n的,而这里的那段区间的大小是log的,所以我猜测复杂度应该是log*常数的。但是不会证,考完试旁边的大佬都十分怀疑我的复杂度,搞得我也非常怀疑,但是。。但是AC了。
正解貌似是O(nlog2n/32)的线段树+压位?听说考场上这么写的全被卡常了,体会到了wys的险恶用心~
回来重码了一发,交到uoj上TLE了,交到BZ上AC了(因为是均摊复杂度嘛~)。
欢迎大佬告诉我这个算法的真正复杂度~
#include <cstdio>
#include <cstring>
#include <iostream>
#define lson x<<1
#define rson x<<1|1
using namespace std;
const int N=30000040;
int n,A,B,nxt,f,len;
int s[N+1<<2],p[50];
void pushdown(int l,int r,int x)
{
if(!s[x]) s[lson]=s[rson]=0;
if(s[x]==r-l+1)
{
int mid=l+r>>1;
s[lson]=mid-l+1,s[rson]=r-mid;
}
}
void pushup(int x)
{
s[x]=s[lson]+s[rson];
}
void dfs(int l,int r,int x)
{
if(l==r)
{
s[x]+=p[l-B];
while(s[x]>1) p[l-B+1]++,s[x]-=2;
while(s[x]<0) p[l-B+1]--,s[x]+=2;
return ;
}
pushdown(l,r,x);
int mid=l+r>>1;
dfs(l,mid,lson),dfs(mid+1,r,rson);
pushup(x);
}
void updata(int l,int r,int x,int a,int b)
{
if(a<=l&&r<=b)
{
dfs(l,r,x);
return ;
}
pushdown(l,r,x);
int mid=l+r>>1;
if(a<=mid) updata(l,mid,lson,a,b);
if(b>mid) updata(mid+1,r,rson,a,b);
pushup(x);
}
void modify(int l,int r,int x,int a,int b,int c)
{
if(a>b) return ;
if(a<=l&&r<=b)
{
s[x]=(r-l+1)*c;
return ;
}
pushdown(l,r,x);
int mid=l+r>>1;
if(a<=mid) modify(l,mid,lson,a,b,c);
if(b>mid) modify(mid+1,r,rson,a,b,c);
pushup(x);
}
void nxt0(int l,int r,int x,int a)
{
if(r<a||nxt<=l||s[x]==r-l+1) return ;
if(l==r)
{
nxt=l;
return ;
}
int mid=l+r>>1;
pushdown(l,r,x);
nxt0(l,mid,lson,a),nxt0(mid+1,r,rson,a);
}
void nxt1(int l,int r,int x,int a)
{
if(r<a||nxt<=l||!s[x]) return ;
if(l==r)
{
nxt=l;
return ;
}
int mid=l+r>>1;
pushdown(l,r,x);
nxt1(l,mid,lson,a),nxt1(mid+1,r,rson,a);
}
int query(int l,int r,int x,int a)
{
if(l==r) return s[x];
pushdown(l,r,x);
int mid=l+r>>1;
if(a<=mid) return query(l,mid,lson,a);
return query(mid+1,r,rson,a);
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),rd(),rd(),rd();
int i;
for(i=1;i<=n;i++)
{
if(rd()==1)
{
A=rd(),B=rd(),f=1,len=0;
if(!A) continue;
if(A<0) f=-1,A=-A;
while(A) p[len++]=(A&1)*f,A>>=1;
p[len++]=0,p[len]=0,updata(0,N,1,B,B+len-1);
if(p[len]>0)
{
nxt=1<<30,nxt0(0,N,1,B+len);
modify(0,N,1,B+len,nxt-1,0),modify(0,N,1,nxt,nxt,1);
}
if(p[len]<0)
{
nxt=1<<30,nxt1(0,N,1,B+len);
modify(0,N,1,B+len,nxt-1,1),modify(0,N,1,nxt,nxt,0);
}
}
else A=rd(),printf("%d\n",query(0,N,1,A));
}
return 0;
}
//10 3 1 2 1 100 0 1 2333 0 1 -233 0 2 5 2 7 2 15 1 5 15 2 15 1 -1 12 2 15
【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)的更多相关文章
- [BZOJ4942][Noi2017]整数 线段树+压位
用线段树来模拟加减法过程,维护连续一段中是否全为0/1. 因为数字很大,我们60位压一位来处理. #include<iostream> #include<cstring> #i ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- S - Query on a tree HDU - 3804 线段树+dfs序
S - Query on a tree HDU - 3804 离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- BZOJ4942 NOI2017整数(线段树)
首先把每32位压成一个unsigned int(当然只要压起来能过就行).如果不考虑进/退位的话,每次只要将加/减上去的数拆成两部分直接单点修改就好了.那么考虑如何维护进/退位.可以发现进位的过程其实 ...
随机推荐
- AC日记——[国家集训队2010]小Z的袜子 cogs 1775
[国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r) ...
- AC日记——[ZJOI2006]物流运输 bzoj 1003
1003 思路: 最短路+dp: 节点在a-b天里不能使用 那么我们准备每一组a-b求一条最短路,如果没有,则用极大值表示: cost[a,b]记录这个最短路: 然后,开始dp: dp[i]=min( ...
- JetBrains软件开发框架下的类似于“.IntelliJIdea2018.1”的配置文件夹的移动
JetBrains软件开发框架下几款软件,如: 会在C盘用户文件夹下生成很大的配置文件夹(IDE config folder),十分占空间,也影响电脑性能. 这些索引目录移动的原理相似,现在以Idea ...
- 【hash】什么是hash,什么是哈希,什么是hash散列,什么是hash一致性算法【关于hash的详解】
什么是hash,什么是哈希,什么是hash散列,什么是hash一致性算法
- Elite Container DELPHI下的一个轻量级IoC对象容器
一.简介: Elite Container是DELPHI下的一个轻量级IoC对象容器(IoC:Inverse of Control,反转控制).它是参考了Java中的Spring框架(主要是配置文件的 ...
- nginx configure 错误记录
1.the HTTP rewrite module requires the PCRE library. ./configure: error: the HTTP rewrite module req ...
- Json格式化工具 JsonViewer下载
免安装版,分享链接永久有效~! 云盘下载地址: http://cloud.suning.com/cloud-web/share/link.htm?sk=401f784782751055ddc21cdb ...
- java模拟http的Get/Post请求,并设置ip与port代理
本文涉及3个基本点: 1.因为很多公司的内网都设有代理,浏览器通过ip与port上网,而java代码模拟http get方式同样需要外网代理: 2.Java实现http的Get/Post请求代码: 3 ...
- > 1366 - Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...' for column 'description' at row 1 字符串格式错误
mysql 执行insert时报错 > 1366 - Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...' for column 'desc ...
- RPi Cam v2 之一:基础及牛刀小试
前言 原创文章,转载引用务必注明链接,水平有限,如有疏漏,欢迎指正. 本文使用markdown写成,为获得更好的阅读体验,可以访问我的博客. 1.unboxing & comparison 包 ...