LOJ2302 「NOI2017」整数
异或和
给定一个序列 a1, a2, ..., an, 满足 a1 + a2... + an ≤ 106,输出这个序列所有的连续和的异或值。
对于100%的数据,1 ≤ n ≤ 105。
题解
首先用前缀和转化成如下式子
\]
显然可以i对每位分开考虑,只需要考虑这一位上 \(1\) 的奇偶性即可。
那么哪些数相减这一位为 \(1\) 呢?关键就是考虑之前的数有没有借位给它,它有没有借位给后面的数。
如果当前扫描到的 \(sum_j\) 的二进制第 \(k\) 位为 \(1\),那么对这一位的答案有贡献的只有那些第 \(k\) 位为 \(1\) 且第 \(k\) 位向右的数大于 \(sum_j\) 第 \(k\) 位向右的数的或者第 \(k\) 位为 \(0\) 且第 \(k\) 位向右的数小于等于 \(sum_j\) 第 \(k\) 位向右的数的数。
第 \(k\) 位为 \(0\) 的情况类似。
时间复杂度 \(O(n \log n \log v)\)。
CO int N=100000+10,V=1000000+10;
int sum[N],val[N];
int cnt[2][V];
void insert(int d,int p,int v){
for(int i=p;i<V;i+=i&-i) cnt[d][i]+=v;
}
int query(int d,int p){
int ans=0;
for(int i=p;i;i-=i&-i) ans+=cnt[d][i];
return ans;
}
int main(){
int n=read<int>();
for(int i=1;i<=n;++i) sum[i]=sum[i-1]+read<int>();
int ans=0;
for(int i=0;i<=19;++i){
int res=0;
insert(0,0+1,1);
for(int j=1;j<=n;++j){
int c=sum[j]>>i&1;
int now=0;
if(c) now=query(0,val[j]+1)+query(1,V-1)-query(1,val[j]+1);
else now=query(1,val[j]+1)+query(0,V-1)-query(0,val[j]+1);
if(now&1) res^=1;
insert(c,val[j]+1,1);
}
if(res&1) ans|=1<<i;
insert(0,0+1,-1);
for(int j=1;j<=n;++j){
int c=sum[j]>>i&1;
insert(c,val[j]+1,-1);
val[j]|=c<<i;
}
}
printf("%d\n",ans);
return 0;
}
整数
题目背景
在人类智慧的山巅,有着一台字长为$1048576$位(此数字与解题无关)的超级计算机,著名理论计算机科
学家P博士正用它进行各种研究。不幸的是,这天台风切断了电力系统,超级计算机
无法工作,而 P 博士明天就要交实验结果了,只好求助于学过OI的你. . . . . .
题目描述
P 博士将他的计算任务抽象为对一个整数的操作。
具体来说,有一个整数$x$,一开始为$0$。
接下来有$n$个操作,每个操作都是以下两种类型中的一种:
1 a b:将$x$加上整数$a\cdot 2^b$,其中$a$为一个整数,$b$为一个非负整数2 k:询问$x$在用二进制表示时,位权为$2^k$的位的值(即这一位上的$1$代表 $2^k$)
保证在任何时候,$x\geqslant 0$。
输入输出格式
输入格式:
输入的第一行包含四个正整数$n,t_1,t_2,t_3$,$n$的含义见题目描述,$t_1$,$t_2$,$t_3$的具体含义见子任务。
接下来$n$行,每行给出一个操作,具体格式和含义见题目描述。
同一行输入的相邻两个元素之间,用恰好一个空格隔开。
输出格式:
对于每个询问操作,输出一行,表示该询问的答案($0$或$1$)。对于加法操作,没有任何输出。
输入输出样例
说明
在所有测试点中,$1\leqslant t_1 \leqslant 3, 1 \leqslant t_2 \leqslant 4, 1 \leqslant t_3 \leqslant 2$。不同的 $t_1, t_2, t_3$ 对应的特殊限制如下:
对于 $t_1 = 1$ 的测试点,满足 $a = 1$
对于 $t_1 = 2$ 的测试点,满足 $|a| = 1$
对于 $t_1 = 3$ 的测试点,满足 $|a| \leqslant 10^9$
对于 $t_2 = 1$ 的测试点,满足 $0 \leqslant b, k \leqslant 30$
对于 $t_2 = 2$ 的测试点,满足 $0 \leqslant b, k \leqslant 100$
对于 $t_2 = 3$ 的测试点,满足 $0 \leqslant b, k \leqslant n$
对于 $t_2 = 4$ 的测试点,满足 $0 \leqslant b, k \leqslant 30n$
对于 $t_3 = 1$ 的测试点,保证所有询问操作都在所有修改操作之后
对于 $t_3 = 2$ 的测试点,不保证询问操作和修改操作的先后顺序
本题共 25 个测试点,每个测试点 4 分。各个测试点的数据范围如下:

题解
均摊分析一下只支持加的二进制计数器的复杂度。给每一个初始1的增加一点势能,表示它以后进位变成0的花费来源。这样的话复杂度就均摊\(O(1)\)了。
所以如果本题只支持加法的话可以利用unsigned int压位,复杂度可以达到\(O(\frac{30n}{32})=O(n)\)
但是可能产生减法怎么办? 大力维护一个加法的结果,再维护一个减法的结果 。
由于保证了\(x\ge 0\),所以只需考虑询问位置即可。做个异或就能得到后面不借位的结果。
至于借位结果,可以用set维护大小不同的块的编号。这样就可以\(O(n\log n)\)了。
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef unsigned uint;
co int N=1e6+1;
int n;
uint inc[N],dec[N];
std::set<int> s;
int main(){
read(n),read<int>(),read<int>(),read<int>();
for(int i=1;i<=n;++i){
if(read<int>()==1){
int a=read<int>(),b=read<int>();
int p=b/32,q=b%32;
if(a>0){
uint st=(uint)a<<q;
uint ic=(uint)a>>(31-q);ic>>=1;
uint od=inc[p];
inc[p]+=st,ic+=od>inc[p];
if(inc[p]^dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
for(++p;ic;++p){
od=inc[p];
inc[p]+=ic,ic=od>inc[p];
if(inc[p]^dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
}
}
else if(a<0){
a=-a;
uint st=(uint)a<<q;
uint ic=(uint)a>>(31-q);ic>>=1;
uint od=dec[p];
dec[p]+=st,ic+=od>dec[p];
if(inc[p]^dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
for(++p;ic;++p){
od=dec[p];
dec[p]+=ic,ic=od>dec[p];
if(inc[p]^dec[p]) s.insert(p);
else if(s.count(p)) s.erase(p);
}
}
}
else{
int b=read<int>();
int p=b/32,q=b%32;
int ans=(inc[p]>>q^dec[p]>>q)&1;
uint v1=inc[p]%(1<<q);
uint v2=dec[p]%(1<<q);
if(v1<v2) printf("%d\n",ans^1);
else if(v1>v2||s.empty()||p<=*s.begin()) printf("%d\n",ans);
else{
std::set<int>::iterator it=s.lower_bound(p);--it;
if(inc[*it]>dec[*it]) printf("%d\n",ans);
else printf("%d\n",ans^1);
}
}
}
return 0;
}
用unsigned压位+分块维护二进制高精加减法
LOJ2302 「NOI2017」整数的更多相关文章
- LibreOJ2302 - 「NOI2017」整数
Portal Description 有一个整数\(x=0\),对其进行\(n(n\leq10^6)\)次操作: 给出\(a(|a|\leq10^9),b(b\leq30n)\),将\(x\)加上\( ...
- 「NOI2017」整数 解题报告
「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...
- LOJ#2302. 「NOI2017」整数
$n \leq 1000000$个操作:一,给$x$加上$a*2^b$:二,问$x$的某个二进制位$k$.$b,k \leq 30n$,$|a| \leq 1e9$. 30暴露了一切..可以把30个二 ...
- LOJ 2302 「NOI2017」整数——压位线段树
题目:https://loj.ac/problem/2302 压30位,a最多落在两个位置上,拆成两次操作. 该位置加了 a 之后,如果要进位或者借位,查询一下连续一段 0 / 1 ,修改掉,再在含有 ...
- loj #2305. 「NOI2017」游戏
#2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...
- LOJ2305 「NOI2017」游戏
「NOI2017」游戏 题目背景 狂野飙车是小 L 最喜欢的游戏.与其他业余玩家不同的是,小 L 在玩游戏之余,还精于研究游戏的设计,因此他有着与众不同的游戏策略. 题目描述 小 L 计划进行$n$场 ...
- LOJ2303 「NOI2017」蚯蚓排队
「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...
- LOJ_2305_「NOI2017」游戏 _2-sat
LOJ_2305_「NOI2017」游戏 _2-sat 题意: 给你一个长度为n的字符串S,其中第i个字符为a表示第i个地图只能用B,C两种赛车,为b表示第i个地图只能用A,C两种赛车,为c表示第i个 ...
- 「NOI2017」游戏
「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...
随机推荐
- Educational Codeforces Round 1 (C) (atan2 + long double | 大数)
这题只能呵呵了. 东搞西搞,折腾快一天,最后用了一个800多行的代码AC了. 好好的题目你卡这种精度干啥. 还有要卡您就多卡点行不,为什么long double 又可以过... 废了N长时间写个了不管 ...
- Idea 使用的技巧和设置
1.自动提示时候,忽绿大小写, setting---->sensitive 2:IntelliJ IDEA报错class is never used 图中的unused declaration选 ...
- WIn10远程:mstsc:出现身份验证错误,要求的函数不支持, 这可能是由于CredSSP加密Oracle修正
a.单击 开始 > 运行,输入 regedit,单击 确定. b.定位到 HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Syst ...
- why factory pattern and when to use factory pattern
1 factory pattern本质上就是对对象创建进行抽象 抽象的好处是显然的,可以方便用户去获取对象. 2 使用factory pattern的时机 第一,当一个对象的创建依赖于其它很多对象的时 ...
- php的json_encode不兼容JSON_UNESCAPED_UNICODE
//php的json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案 function _json_encode($value) { if (version_compare( ...
- 我的Android进阶之旅------>解决 Error: ShouldNotReachHere() 问题
在Android项目中创建一个包含main()方法的类,直接右键运行该类时会报如下错误: # # An unexpected error has been detected by Java Runti ...
- 7.Django模型类的定义和管理
Django的模型类是给ORM层服务的 1.每个数据模型都是django.db.models.Model的子类. 2.它的父类Model包含了所有必要的和数据库交互的方法,并提供了定义数据库字段的语法 ...
- python cookbook第三版学习笔记十八:可由用户修改的装饰器
定义一个属性可由用户修改的装饰器: 在前面的介绍中使用装饰器来包装函数,这一章来介绍下如何让用户调整装饰器的属性. 首先来看下代码: from functools import wraps,parti ...
- linux下tomcat的配置及项目的部署流程
Java的安装配置 1. 在/etc/profile文件中配置相应的信息(如下) export JAVA_HOME=/usr/java/jdk1.6.0_20 export JRE_HOME=/usr ...
- js 动态加载事件的几种方法总结
本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添 ...