D2. 388535 (Hard Version)

D2. 388535 (Hard Version)

题目大意:

题目意思是,给一个区间l~r(l<=0),再给长度为r-l+1的数列a。

给一个序列a,0~r的一个排列要整体Xor 上一个x后可以得到给定的a,求出x。

思路和代码:

设题目给的操作后序列为a,原始序列为p(l~r的一个排列),有:

$$
p \bigoplus x = a
$$

$$
p \bigoplus x \bigoplus x = a \bigoplus x
$$

$$
得到:p = a\bigoplus x
$$

所以我们只要枚举x,看能不能得到p就行。暴力做法是O(n2logn)的,没什么用。

我们再思考一下,由Xor的性质可以知道:p中的数字是两两不同的,所以a中的数字也是两两不同的。

在这题中,排列中的pi是两两不同的,异或后的ai也是两两不同的。pi和ai之间有一一对应的双向的映射关系(一个萝卜一个坑)。这种情况下,只要找到max(ai Xor x)= r,min(ai Xor x)= l即可确定。区间中间的不用管。

那么我们只要找到一个x,使得以下两个条件同时满足即可:
$$
max{a_i \bigoplus x} == r
$$

$$
min{a_i \bigoplus x} == l
$$

而我们知道,给定x后在数组中找一个ai使得其Xor最大或者最小是01字典树的经典应用,复杂度O(logn) 。

如果我们从0开始暴力枚举每一个x,会TLE。

所以需要进行优化。

思考必定有一个i,使得ai Xor x = l。那么和上面一样的想法,两边Xor上 ai,可得必定有一个ai满足:x=l Xor ai。

所以可以枚举ai Xor l。

对了,这题贼坑,我用全局变量的时候memset直接超时,所以vector大法好啊~

ll n , m , k ; 
ll a[N] ;
//ll nxt[N * 30][2] 
ll idx ;

void insrt(ll x , vct<vct<ll> > &nxt){//建树过程
	ll now = 0 ;
	drep(i , 0 , MAXBIT){
		bool y = (x >> i) & 1 ;
		if(!nxt[now][y]) nxt[now][y] = ++ idx ;
		now = nxt[now][y] ;
	}
}

ll query_max(ll x , vct<vct<ll> > &nxt){
	ll now = 0 , res = 0 ;
	drep(i , 0 , MAXBIT){
		bool y = ((x >> i) & 1) ;
		if(nxt[now][y^1]){
			res += (1 << i) ;
			now = nxt[now][y^1] ;
		}else now = nxt[now][y] ;
	}
	return res ;
}

ll query_min(ll x , vct<vct<ll> > &nxt){
	ll now = 0 , res = 0 ;
	drep(i , 0 , MAXBIT){
		bool y = (x >> i) & 1 ;
		if(nxt[now][y]) now = nxt[now][y] ;
		else{
			now = nxt[now][y^1] ;
			res += (1 << i) ;
		}
	}
	return res ;
}

void solve(){
	idx = 0 ;
	//memset(nxt , 0 , sizeof(nxt)) ;
	ll l , r ;
	cin >> l >> r ;
	vct<vct<ll> > nxt((r - l + 1) * 32 , vct<ll>(2 , 0)) ;
	
	rep(i , l , r){
		cin >> a[i - l] ;
		insrt(a[i - l] , nxt) ;
	}
	
	rep(i , l , r){
		ll ans = a[i - l] ^ l ;
		ll L = query_min(ans , nxt) ;
		ll R = query_max(ans , nxt) ;
		//cout << L << " " << R << "\n" ;
 		if(L == l && r == R){
			cout << ans << "\n" ;
			return ;
		}
	}
	
}//code_by_tyrii 
小结:

遇到位运算需要每一位拆解开来看。

遇到异或则需要想到奇次异或和偶次异或的变反和不变的性质。

异或的题目可以用01trie来解决。

posted @ 2022-03-28 17:46  tyrii  阅读(167)  评论(0)    收藏  举报