[ROI 2017 Day 1] 排序幻觉 题解
感觉完全不到蓝题。下文
考虑把所有的条件拆开来处理最后再合并,即考虑确定
- 当
x=y 时,显然b 可以取全体非负整数; - 当
x\ne y 时,考虑c=x\oplus y 在二进制下的最高位\mathrm{highbit}(c) (即x 和y 最高的不相同的位),显然b 在这一位的取值决定了x 和y 的大小,故如果x<y 那么b 该位应为0 ,否则为1 ;b 的其他位可以随便取。
于是对于每个
修改操作是容易的,只需要把原来相邻的两对数(
求 __builtin_clz 函数,该函数可以返回一个无符号整数二进制表示下前导零的个数(默认是 __builtin_clzll 则是
放代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
int n; cin>>n;
vector<int> a(n);
for(auto &i:a)cin>>i;
vector<array<int,2> > c(31);
auto f=[&](int p,int d){
if(int r=a[p-1]^a[p];r)
c[31-__builtin_clz(r)][a[p-1]>a[p]]+=d;
}; // 加入(d = 1)/ 撤销(d = -1)一个条件
auto r=[&](){
int w=0;
for(int i=0;i<31;i++)
if(c[i][1]){
if(c[i][0])return -1; // 矛盾
w|=1<<i; // 该位需要为 1
}
return w;
}; // 求解最小的 b
for(int i=1;i<n;i++)
f(i,1); // 初始化
cout<<r()<<'\n';
int q; cin>>q;
while(q--){
int p,x,c=0; cin>>p>>x,p--;
if(p<n-1)f(p+1,-1); if(p)f(p,-1); // 撤销
if(a[p]=x;p<n-1)f(p+1,1); if(p)f(p,1); // 加入
cout<<r()<<'\n';
}
return 0;
}