【FJWC】day3简要题解

1.sort

直接用桶维护“相邻两个数异或值的二进制最高位”即可。
时间复杂度 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;
}


2.queue

读错题并且肝了2h最终获得5分好成绩的zz在此。。。

看漏了这句话依旧能过样例:

此时如果女性专用单间为空,当前队列里最
前的一位女性会直接进入。

那么就是任意偶数长度后缀 c n t F ≥ c n t M cnt_F\geq cnt_M cntFcntM
直接 O ( n ) O(n) O(n)贪心。

但这道题数列要复读!

考虑复读同一段时,如果存在后缀不合法,一定最前一段差最大,然后贪心取一下。
有点麻烦,等明天看了题解再说吧。


3.game

JOISC2016 原题:
loj2731


总结

T1依旧是细节问题

T2,3都死于读题

全是最基本的不该犯的问题啊(T_T)

你可能感兴趣的:(test,贪心)