NOIP提高模拟 Binary
来源:互联网 发布:mac系统怎样翻墙 编辑:程序博客网 时间:2024/06/05 01:14
Description
Data Constraint
Solution
我们考虑到询问and、or、xor一个数之类的问题,通常都是将二进制上的位分开来处理。想到这个就好做了。我们开20颗树状数组,第i颗树状数组记录1~n中的每个数保留后i位之后,权值在0~2i−1 的数的个数,也就是个权值线段树。对于一个修改操作,我们只需将原本ax 在树状数组中的值的位置上减1,在y在树状数组中的位置加1,更新一下ax 即可。
而对于查询操作,我们考虑第i位对于答案的贡献。第i位对于答案的贡献就是区间在2i−1 ~2i -1的数的个数*2i−1 (其中y的第i位必须为1)。但此时多了个x对答案产生了影响,所以我们将区间调整为2i−1−x ~2i−1−x (其中x保留后i位)。我们可能会问,当2i−1 < x时怎么处理?我们发现,设k=x-2^{i-1},2i−1−k ~2i−1 与2i−1−x ~0是等价的。因为2i−1−k ~2i−1 里的每个数+x后导致进位,而我们并不关心进位的那一位,我们只关心剩余下来的i位,这就相当于算法中的取模,所以2i−1−k ~2i−1 里的每个数+x后对第i位都是有贡献的,因为他们第i位都有值。
所以,这个算法的复杂度就降为O(Nlog2 n)。
代码
#include<iostream>#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define ll long longusing namespace std;const int maxn=100005,maxn1=21,maxn2=1048580;int a[maxn],n,m,i,t,k,j,l,x,f[maxn1+3][maxn2],ch,y,z1;long long ans;int lowbit(int x){ return x & (-x);}void insert(int z,int x,int y){ if (x>z1) return; f[z][x]+=y; insert(z,x+lowbit(x),y);}ll find(int z,int x){ if (x<1) return 0; return f[z][x]+find(z,x-lowbit(x));}int main(){ //freopen("data.in","r",stdin);freopen("data.out","w",stdout); scanf("%d%d",&n,&m); for (i=1;i<=n;i++){ scanf("%d",&a[i]);t=a[i]; for (j=maxn1;j>=1;j--){ if (t>(1<<j)-1) t=t-(1 << j); z1=(1<<j); insert(j,t+1,1); } } for (i=1;i<=m;i++){ scanf("%d%d%d",&ch,&x,&y); if (ch==1){ t=a[x]; for (j=maxn1;j>=1;j--){ if (t>(1<<j)-1) t=t-(1 << j); z1=(1<<j); insert(j,t+1,-1); } t=y; for (j=maxn1;j>=1;j--){ if (t>(1<<j)-1) t=t-(1 << j);z1=(1<<j); insert(j,t+1,1); } a[x]=y; }else{ ans=0; for (j=maxn1;j>=1;j--) if ((1<<(j-1))&y){ x=x & ((1 << j)-1); t=1<<(j-1);k=(1<<j)-1;z1=1<<(j-1); t=(t+(1<<j)-x)%(1<<j);k=(k-x+(1<<j))%(1<<j); if (t<=k) ans+=(find(j,k+1)-find(j,t))*z1; else ans+=(find(j,k+1)+find(j,1<<j)-find(j,t))*z1; } printf("%lld\n",ans); } }}
2 0
- NOIP提高模拟 Binary
- 【NOIP提高】Binary
- NOIP提高组 20151029模拟
- noip提高组模拟Matrix
- NOIP提高组模拟 Value
- 【NOIP提高组模拟】看电影
- NOIP提高组模拟 幻象
- 【NOIP提高组模拟】幻象
- NOIP提高组模拟 百团大战
- 【初中部 NOIP提高组 】模拟赛A
- 2016.07.08noip提高组模拟总结
- Noip提高组模拟【2016.8.17】
- 【NOIP提高模拟】奇洛金卡达
- 【NOIP提高组模拟】树塔狂想曲
- NOIP提高组模拟 树上摩托
- 【NOIP提高组模拟】树上摩托
- NOIP提高组11.11~11.13模拟总结
- 【NOIP 2003提高】侦探推理 模拟
- Value【NOIP2016提高A组模拟8.17】
- Android ListView部分属性介绍
- 分布式搜索Elasticsearch——删除指定索引
- Intent传递对象——Serializable和Parcelable区别
- 网络爬虫——原理简介
- NOIP提高模拟 Binary
- JAVA_Apache_POI操作EXCEL(与第一个sheet相同去重)
- 51Nod-1076-2条不相交的路径
- 2016/8/17 学会学习
- java web整合开发笔记
- 机器学习之k-means算法
- 邮箱验证正则表达式【转载】
- java正则表达式学习
- 多线程问题的总结