与非
2016-07-07 16:36
267 查看
题目大意
分类讨论
假若一个0左边有数,那么执行到0这里结果肯定为1。只有左边没数的0和1与1与非会产生0,假若能统计得到的0的个数,便可以计算异或和。
连续一段1如果最左端有数,这一段有j个1,可以造成j/2上取整个0。
于是我们可以预处理前缀答案,还有一个位置往左最多扩展(是1即可扩展),有啥用呢?待会会讲。
l=1我们就可以直接输出了,必须判掉这种情况不然会有麻烦。
然后我们可以分类讨论:
如果第l位是0,那么就出现了一个0,而且因为是0,所以前面没有任何影响(即其不会存在于连续1中)。
l=r的话直接输出1。
l不等于r呢,0后面那段有多少个1我们需要知道,首先呢我们知道这一段的答案是可以用前缀和求出的,但这个不是对的,因为我们是把0当做了左边有数,即认为到了0这儿前缀与非就是1,但现实是0这儿前缀与非应该是0,所以应该减掉误的加上对的。
如果第l位是1,那么我们得到左边有j个1,l往右有k个1。
sum[r]=sum[l-1]-(j+1)/2+ans-k/2+(j+k+1)/2
ans=sum[r]-sum[l-1]+(j+1)/2+k/2-(j+k+1)/2
这样就是对的吗?不一定,如果往左一定延伸到了首部,那就出了问题,因为我们会认为前面有一个0让这一段1靠着,所造成的影响就是除以2上取整,但现在没有这个0,一开始就是1,就应该是除以2下取整。
只有这种情况会错吗?不一定,还有你虽然没延伸到头,但你延伸的位置所靠的0就是头,我们以为到0这里前缀与非是1,但这里实际是0。
于是这就是所有情况,求往左延伸直接使用left数组,求往右延伸可以二分然后利用left数组来判定。
最后吐槽一句,打这种方法好烧脑……
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=4000000+10; int a[maxn],sum[maxn],num[maxn],left[maxn]; int i,j,k,l,r,t,n,m,top,ans; bool czy; int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } int binary(int x,int y){ int l=0,r=y,mid; while (l<r){ mid=(l+r+1)/2; if (left[x+mid-1]>=mid) l=mid;else r=mid-1; } return l; } int main(){ czy=1; n=read(); while (n--){ t=read(); if (t==1){ j=read(); if (czy) j^=ans; a[++top]=j; num[top]=top==1?a[top]:!(num[top-1]&a[top]); sum[top]=sum[top-1]+(!num[top]); left[top]=(j?left[top-1]+1:0); } else{ l=read();r=read(); if (czy&&ans){ l=top-l+1; r=top-r+1; swap(l,r); } if (l==1) ans=sum[r]; else{ if (!a[l]){ if (l==r) ans=1; else{ j=binary(l+1,r-l); ans=sum[r]-sum[l-1]-(j+1)/2+(j+2)/2; } } else{ j=left[l-1]; k=binary(l,r-l+1); ans=sum[r]-sum[l-1]+(j+1)/2+k/2-(j+k+1)/2; if (j==l-1||j==l-2&&a[1]==0) ans=ans+(j+k+1)/2-(j+k)/2-(j+1)/2+j/2; } } ans=(r-l+1-ans)%2; printf("%d\n",ans); } } }
相关文章推荐
- 力学 —— 圆周运动
- 1150. 【克罗地亚】NIKOLA (Standard IO)
- join查询
- lang3实用Utils
- instsrv.exe下载和使用方法(微软Windows Server 2003 Resource Kit Tools工具中的一个)
- 微信开放平台 获取 component_verify_ticket
- Smaug Coverage
- python pycurl模块
- web.xml配置文件详解
- oracle 日期
- iOS 绘图之drawImage
- 优化MyBatis配置文件中的配置_3
- 红外遥控协议-NEC协议
- MySQL传智播客--Lession13-Lession24笔记
- Oracle EBS修改IP地址
- java 利用反射构造泛型类
- html基础
- 校外分散实习(2)
- 【jmeter】浅说 think time
- 关于枚举