javaee论坛

普通会员

225648

帖子

335

回复

349

积分

楼主
发表于 2019-11-07 13:06:04 | 查看: 144 | 回复: 2

膜拜azui(azui.cpp/c/pas)

问题描述

一天,小A给了J·G一道水题,J·G一眼秒了,现在J·G想考考你们:小A有N个灯,排成了一列,现在小A给出来一个叫做azui的奇葩操作,我们把开着的灯看作数字1,把关着的灯看作数字0,定义0azui0=1,0azui1=0,1azui1=1,1azui0=0。现在小A有N个问题:azui(l,r),表示询问从左往右的第l个灯向右一个一个azui到第r个灯的结果是什么。

输入

第1行一个整数N表示序列的长度。第2行N个整数Ai,每个数不是0就是1,表示灯是关的还是开的。第3行一个整数M表示询问的个数。第4~M+3行,每行两个整数l和r,表示询问azui(l,r)。

输出

共M行,第i行回答第i个询问。

样例输入

51010152334451314

样例输出

00001

数据范围

对于30%的数据,N和M<=5000对于80%的数据,N和M<=500000对于100%的数据,N和M<=1000000

思路

看到运算法则的第一眼,我就想到了“反异或”,即aazuib=!(a^b)……事实上:aazuib=a==b难道我天生就有装逼的基因但都没有问题,这里的azui操作的正规名字叫做“同或”(与异或相对==)。

扯完名字和运算的问题,怎么做呢?看到了区间询问,首先想到了前缀“和”,当然肯定不是“和”,硬要说,就叫“前缀azui”吧==。

但是用前缀和来举个例子:sum(l,r)=ans[r]-ans[l-1](ans[i]为1+2+…+i)注意这个减号,于是就发现要用加法的逆运算减法才能抵消掉ans[l-1]。

所以我考试时想了好久,azui的逆运算是什么?我举了几个例子,貌似azui的逆运算就是azui!为什么,我也不知道==,于是我就这样做了……然后用暴力程序对拍,并没有问题。于是就AC了==。

最后如果l==1特殊处理一下直接输出ans[r]。

代码#include<cstdio>intread(){intx=0,f=1;chars=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}returnx*f;}#defineMAXN1000000boolans[MAXN+5];intN,M;boolazui(boolx,booly){return!(x^y);}//计算azui(事实上直接returnx==y即可)intmain(){N=read();ans[1]=read();//ans为前缀azui数组,ans[1]要单独处理,不然有问题for(inti=2;i<=N;i++)ans[i]=azui(ans[i-1],read());M=read();while(M--){intl=read(),r=read();printf("%d\n",l==1?ans[r]:azui(ans[r],ans[l-1]));}return0;}

普通会员

0

帖子

323

回复

352

积分
沙发
发表于 2019-12-08 07:47:15

好好好

普通会员

0

帖子

293

回复

303

积分
板凳
发表于 2024-03-28 00:29:48

不错

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017