BZOJ4942 & UOJ314:[NOI2017]整数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4942
https://www.luogu.org/problemnew/show/P3822
题面是markdown形式的所以我传不上……
UPD:18.5.11改成对参考代码的理解失误。
参考:http://www.cnblogs.com/RabbitHu/p/UOJ314.html仔细思考之后发现lazy标记可以不下传,因为区间修改都是改0/INF,单点修改就直接改就行了……
(晚上睡前突然发现这个sb问题然后太晚了只好现在改。)
暴力修改显然是不行的。
考虑让你改的是a*2^b,已经明示了想让你直接修改二进制位,于是把a用O(log)时间拆成二进制然后log次加减,期间的进位退位问题用参考博客的方法可以O(log)实现。
但问题是位数一共有3e7……显然会T的。
于是压60位,这样时间复杂度就有保证了。
(我记得以前有人批评松松松就是因为他WC出神题然后NOI出签到题……woc我怕不是送分题都做不出来我退役吧。)
- #include<cstdio>
- #include<queue>
- #include<cctype>
- #include<cstring>
- #include<cmath>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- const int N=5e5+;
- const int B=;
- const ll INF=(1LL<<B)-;
- inline ll read(){
- ll X=,w=;char ch=;
- while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
- while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
- return w?-X:X;
- }
- ll lazy[N*+],val[N*+];
- int pos[N*+];
- bool tag[N*+][];
- inline void upt(int a){
- tag[a][]=tag[a<<][]&tag[a<<|][];
- tag[a][]=tag[a<<][]&tag[a<<|][];
- }
- inline void mdy(int a,ll x){
- if(pos[a]!=-)val[pos[a]]=x;
- if(x==)tag[a][]=,tag[a][]=;
- else if(x==INF)tag[a][]=,tag[a][]=;
- else tag[a][]=tag[a][]=;
- lazy[a]=x;
- }
- inline void push(int a){
- if(lazy[a]==-)return;
- mdy(a<<,lazy[a]);
- mdy(a<<|,lazy[a]);
- lazy[a]=-;
- }
- void build(int a,int l,int r){
- tag[a][]=;lazy[a]=-;pos[a]=-;
- if(l==r){
- pos[a]=l;
- return;
- }
- int mid=(l+r)>>;
- build(a<<,l,mid);build(a<<|,mid+,r);
- }
- void modify(int a,int l,int r,int l1,int r1,ll x){
- if(r<l1||r1<l||l1>r1)return;
- if(l1<=l&&r<=r1){
- mdy(a,x);
- return;
- }
- push(a);
- int mid=(l+r)>>;
- modify(a<<,l,mid,l1,r1,x);
- modify(a<<|,mid+,r,l1,r1,x);
- upt(a);
- }
- ll query(int a,int l,int r,int p){
- if(l==r)return val[l];
- push(a);
- int mid=(l+r)>>;
- if(p<=mid)return query(a<<,l,mid,p);
- else return query(a<<|,mid+,r,p);
- }
- int find(int a,int l,int r,int p,int o){
- if(tag[a][!o])return -;
- if(l==r)return l;
- push(a);
- int mid=(l+r)>>,tmp;
- if(p<=mid&&(tmp=find(a<<,l,mid,p,o))!=-)return tmp;
- return find(a<<|,mid+,r,p,o);
- }
- void add(int p,ll x){
- ll tmp=query(,,N,p);
- modify(,,N,p,p,(tmp+x)&INF);
- if(tmp+x>INF){
- int r=find(,,N,p+,);
- modify(,,N,r,r,val[r]+);
- modify(,,N,p+,r-,);
- }
- }
- void del(int p,ll x){
- ll tmp=query(,,N,p);
- modify(,,N,p,p,(tmp-x)&INF);
- if(tmp-x<){
- int r=find(,,N,p+,);
- modify(,,N,r,r,val[r]-);
- modify(,,N,p+,r-,INF);
- }
- }
- int main(){
- int n=read();read(),read(),read();
- build(,,N);
- for(int i=;i<=n;i++){
- int op=read();
- if(op==){
- ll a=read(),b=read();
- ll p=b/B,m=b%B;
- if(a>){
- ll x=(ll)a<<m&INF;
- if(x)add(p,x);
- p++;a>>=(B-m);
- if(a)add(p,a);
- }else{
- a=-a;
- ll x=(ll)a<<m&INF;
- if(x)del(p,x);
- p++;a>>=(B-m);
- if(a)del(p,a);
- }
- }else{
- ll k=read();
- printf("%lld\n",query(,,N,k/B)>>(k%B)&);
- }
- }
- return ;
- }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +
+++++++++++++++++++++++++++++++++++++++++++
BZOJ4942 & UOJ314:[NOI2017]整数——题解的更多相关文章
- 【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)
[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依 ...
- 【BZOJ4942】[NOI2017]整数(分块)
[BZOJ4942][NOI2017]整数(分块) 题面 BZOJ 洛谷 题解 暴力就是真正的暴力,直接手动模拟进位就好了. 此时复杂度是模拟的复杂度加上单次询问的\(O(1)\). 所以我们需要优化 ...
- 【bzoj4942】[Noi2017]整数 压位+线段树
题目描述 P 博士将他的计算任务抽象为对一个整数的操作. 具体来说,有一个整数 $x$ ,一开始为0. 接下来有 $n$ 个操作,每个操作都是以下两种类型中的一种: 1 a b :将 $x$ 加上整数 ...
- [Bzoj4942][Noi2017]整数(线段树)
4942: [Noi2017]整数 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 363 Solved: 237[Submit][Status][D ...
- NOI2017整数
NOI2017 整数 题意: 让你实现两个操作: 1 \(a\) \(b\):将\(x\)加上整数\(a \cdot 2 ^ b\),其中 \(a\)为一个整数,\(b\)为一个非负整数 2 \( ...
- C#版 - Leetcode 13. 罗马数字转整数 - 题解
C#版 - Leetcode 13. 罗马数字转整数 - 题解 Leetcode 13. Roman to Integer 在线提交: https://leetcode.com/problems/ro ...
- [NOI2017]整数
[NOI2017]整数 题目大意: \(n(n\le10^6)\)次操作维护一个长度为\(30n\)的二进制整数\(x\),支持以下两种操作: 将这个整数加上\(a\cdot2^b(|a|\le10^ ...
- BZOJ4942【noi2017】整数
题目背景 在人类智慧的山巅,有着一台字长为10485761048576 位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 ...
- [BZOJ4942] [NOI2017]整数
题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...
随机推荐
- oracle 建立一个视图,然后授权其他用户访问
grant select on V_LIC_ENTRY_HZ_STATUS to ielicr2013; create or replace view dept_sum_vw (name,minsal ...
- CentOS6.5进不去系统,修复
今天进系统出现问题了,然后在网上搜索了一下解决方案解决了,把解决方法记录下来,方便以后查阅. 输入root密码 #mount | grep "on /" //得到root用户所在分 ...
- redis 学习笔记三
一.redis 复制 数据库复制指的是发生在不同数据库实例之间,单向的信息传播的行为,通常由被复制方和复制方组成,被复制方和复制方之间建立网络连接,复制方式通常为被复制方主动将数据发送到复制方,复制方 ...
- JQuery.extend扩展实现同步post请求
有时需要在jQuery中实现同步post请求,而jquery自带的是异步,需要通过JQuery.extend扩展. 支持ie和firefox,方法转载而来.需要在submit前将form.append ...
- Cannot assign requested address (connect failed)
压测时,应用服务器报错:Cannot assign requested address (connect failed) 经检查,由于应用服务器,频繁发起http请求,由于每次连接都在很短的时间内结束 ...
- PyCharm 2018 最新激活方式总结(最新最全最有效)!!!
PyCharm 2018 最新激活方式总结(最新最全最有效!!!) pycharm2018 是目前python编程的主要应用工具,具有非常广泛的应用,不过对于它的破解一直比较麻烦,这里我为大家提供了三 ...
- MATLAB实现连续周期信号的频谱分析(正余弦波信号举例)
关于MATLAB实现连续信号的频谱分析,以正余弦波信号频谱分析为例分析如下: 1.含有频率f ,2f和3f的正弦波叠加信号,即: 其中,f =500Hz.试采用Matlab仿真软件对该信号进行频谱分析 ...
- flume-kafka-storm-hdfs-hadoop-hbase
# bigdata-demo 项目地址: https://github.com/windwant/bigdata-demo.git hadoop: hadoop hdfs操作 log输出到flume ...
- 加油吧 骚年QAQ
本随笔文章,由个人博客(鸟不拉屎)转移至博客园 写于:2017 年 11 月 08 日 原地址:https://niaobulashi.com/archives/fighting.html --- 想 ...
- 181. Flip Bits【LintCode, by java】
Description Determine the number of bits required to flip if you want to convert integer n to intege ...