1001:^ & ^
对第i位,如果A和B的第i位都是1,那么C的这一位需要为1,否则取0.C必须为正数,所以C可以取0的时候,要看A和B最小的一个为1一个为0的位出现的位置last,让C为1<<last(这样才能保证(A ^ C)&( B ^ C)最小)。如果没有这样的位置,就让C为1.
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-(x)))
using namespace std;
int main()
{
int T;cin>>T;
ll a,b,c;
while(T--){
scanf("%lld%lld", &a, &b);
c = 0;
ll k = 1;
int last = 0;
for(int i = 32; i >= 0; --i){
ll ba = (a&(k<<i)), bb = (b&(k<<i));
if(ba && bb){
c |= (k<<i);
}
else if(ba^bb) last = i;
}
if(c == 0) c = 1<<last;
cout<<c<<endl;
}
}
1002: array
做法1:
在[1,r]找没出现的,相当于在[r+1,end]找出现过的,在最后一个位置加一个n+1。用主席树找[r+1,end]出现的最小的大于等于k的数字。每个操作一可以看成在end位置添加一个a[pos]。
#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-(x)))
#define mid ((l+r)>>1)
using namespace std;
const int maxn = 2e5 + 50;
int sz[maxn*20], lc[maxn*20], rc[maxn*20];
int T[maxn];
int a[maxn];
int n, m;
int tot;
void build(int pre, int &cur, int l, int r, int pos){
cur = ++tot;
sz[cur] = sz[pre]+1;
lc[cur] = lc[pre]; rc[cur] = rc[pre];
if(l == r) return;
if(pos <= mid)
build(lc[pre], lc[cur], l, mid, pos);
else
build(rc[pre], rc[cur], mid+1, r, pos);
}
int qry(int pre, int cur, int l, int r, int k)
{
if(sz[cur] - sz[pre] == 0) return -1;
if(l == r){
return l