直接用桶维护“相邻两个数异或值的二进制最高位”即可。
时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间复杂度 O ( n ) O(n) O(n)
判-1写WA了!
for(i=0;i<=30;++i) if((bn[i] && mst[i])) break;
b n [ i ] , m s t [ i ] bn[i],mst[i] bn[i],mst[i]分别表示一共有几个相邻位置要求第 i i i位不能选/必须选( b a n / m u s t ban/must ban/must),若 b n [ i ] , m s t [ i ] bn[i],mst[i] bn[i],mst[i]均>0则则无解。
然后我假装可以 O ( 1 ) O(1) O(1)特判,于是写成了在修改时直接维护:
if((bn[x]==1 && mst[x])) cot++;
if(bn[x]==1 && mst[x]==1) cot--;
若 c o t > 0 cot>0 cot>0则无解。
然而它们不一定同时为1才出现啊!过了小样例没有仔细想,就煞笔了。
100pts → \to → 75pts
#include
#include
#include
#include
#include
using namespace std;
const int N=1e6+10;
int n,a[N],m,cnt[35],cot,ans;
int bn[35],mst[35];
char cp,buf[N],wbuf[N],os[100];
int p1,p2,p3;
inline char gc(){
if(p1==p2) p1=0,p2=fread(buf,1,N,stdin);
return p1==p2?EOF:buf[p1++];
}
inline void rd(int &x)
{
cp=getchar();x=0;
for(;!isdigit(cp);cp=getchar());
for(;isdigit(cp);cp=getchar()) x=x*10+(cp^48);
}
inline void wchar(char x)
{
if(p3==N) fwrite(wbuf,1,N,stdout),p3=0;
wbuf[p3++]=x;
}
inline int fd(int x)
{
if(!x) return -1;
int l=0,r=30,mid,y;
for(;l<=r;){mid=(l+r)>>1;(x>=(1<<mid))?(l=(y=mid)+1):(r=mid-1);}
return y;
}
void chg(int x,int y,int op)
{
x=fd(x);if(x==-1) return;
if(op){
if((a[y]>>x)&1) bn[x]++;else{mst[x]++;ans|=(1<<x);}
}else{
if((a[y]>>x)&1) bn[x]--;else{mst[x]--;if((!mst[x])) ans^=(1<<x);}
}
}
inline void prit()
{
int i;
for(i=0;i<=30;++i) if((bn[i] && mst[i])) break;
if(i<=30){
wchar('-');wchar('1');
}
else{
int x=ans,re=0;
for(;(!re)||(x);x/=10) os[++re]='0'+(x%10);
for(;re;--re) wchar(os[re]);
}
if(m>1) wchar('\n');
}
int main(){
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
int i,x,y,l,r,mid;
rd(n);for(i=1;i<=n;++i) rd(a[i]);
for(i=2;i<=n;++i) chg(a[i-1]^a[i],i,1);
rd(m);m++;prit();m--;
for(;m;--m){
rd(x);rd(y);
if(x>1) chg(a[x]^a[x-1],x,0);
if(x<n) chg(a[x]^a[x+1],x+1,0);
a[x]=y;
if(x>1) chg(a[x]^a[x-1],x,1);
if(x<n) chg(a[x]^a[x+1],x+1,1);
prit();
}
if(p3) fwrite(wbuf,1,p3,stdout);
fclose(stdin);fclose(stdout);
return 0;
}
读错题并且肝了2h最终获得5分好成绩的zz在此。。。
看漏了这句话依旧能过样例:
此时如果女性专用单间为空,当前队列里最
前的一位女性会直接进入。
那么就是任意偶数长度后缀 c n t F ≥ c n t M cnt_F\geq cnt_M cntF≥cntM。
直接 O ( n ) O(n) O(n)贪心。
但这道题数列要复读!
考虑复读同一段时,如果存在后缀不合法,一定最前一段差最大,然后贪心取一下。
有点麻烦,等明天看了题解再说吧。
JOISC2016 原题:
loj2731
总结
T1依旧是细节问题
T2,3都死于读题。
全是最基本的不该犯的问题啊(T_T)