C o d e f o r c e s R o u n d 922 ( D i v . 2 ) \Huge{Codeforces Round 922 (Div. 2)} CodeforcesRound922(Div.2)
文章目录
- Problems A. Brick Wall
- 思路
- 标程
- Problems B. Minimize Inversions
- 思路
- 标程
- Problems C. XOR-distance
- 思路
- 标程
Problems A. Brick Wall
思路
给定一个大小为 n × m n\times m n×m的墙,并给出无限个大小为 1 × x ( 2 ≤ x ) 1\times x(2\le x) 1×x(2≤x)的砖,要求刚好将墙铺满,若砖横着放,则稳定性 + 1 +1 +1,否则 − 1 -1 −1,求最大稳定性。
若令稳定性最大,我们考虑全部用大小为的砖,采用横铺,若每排不能刚好铺满,则最后一块砖就选长一点即可。
标程
void Solved() {int n, m; cin >> n >> m;cout << m / 2 * n << endl;
}
Problems B. Minimize Inversions
思路
给出两个长度为n的数组,要求同时对两数组操作,每次操作选中两个下标,并进行交换。要求操作后的两数组中逆序对最少,并输出操作后的两数组。
要令两数组的逆序数最少,只需将其中一个数组变为升序,即一个数组中逆序数个数为零,则两数组的逆序对个数就是最少。
标程
void Solved() {int n; cin >> n;vector<PII> a(n), b(n);for(auto &i : a) cin >> i.fi;for(auto &i : a) cin >> i.se;sort(ALL(a));for(int i = 0; i < n; i ++ ) {cout << a[i].fi << " \n"[i == n - 1];}for(int i = 0; i < n; i ++ ) {cout << a[i].se << " \n"[i == n - 1];}
}
Problems C. XOR-distance
思路
给出三个整数 a , b , r ( 0 ≤ a , b , r ≤ 1 0 18 ) a,b,r(0\le a,b,r\le 10^{18}) a,b,r(0≤a,b,r≤1018),求所有 0 ≤ x ≤ r 0\le x \le r 0≤x≤r中 ∣ ( a x o r x ) − ( b x o r x ) ∣ |(a\ xor\ x) - (b\ xor\ x)| ∣(a xor x)−(b xor x)∣的最小值。
数比较大,暴力显然不可能。
通过进行二进制拆分,可以近似得到 ( a − b ) = 2 a 1 + 2 a 2 + 2 a i − 2 b 1 − 2 b 2 − 2 b j (a-b) = 2^{a_1} + 2^{a_2} + 2^{a_i}-2^{b_1}-2^{b_2}-2^{b_j} (a−b)=2a1+2a2+2ai−2b1−2b2−2bj这样的形式。
对于上面的形式,若令 ∣ a − b ∣ |a-b| ∣a−b∣最小,需要将较大数 a a a的最高位不变,其余 b b b中没有的位给变为负即可。
通过观察题目所求,根据异或的性质(同为零,异为一)。对于所求值,我们可以将 x x x视作将== a o r b a\ or \ b a or b==的二进制下的某些位置取反,以达到取反后差值最小。
根据这一规律,我们判断 a , b a,b a,b的相同位,从高位开始,较大数为 1 1 1且较小数为 0 0 0的位取反(即异或),但需要注意,较数的最高位应保持不变。经过这样操作后的两数差值会达到最小。
然后按位进行判断,并用x进行保存 ( x < r ) (x<r) (x<r)即可。
标程
void Solved() {LL a, b, r; cin >> a >> b >> r;if(a < b) swap(a, b);LL cur = 0;int t = 0;for(int i = 60; i >= 0; i -- ) {int x = a >> i & 1;int y = b >> i & 1;if(x <= y) continue;if(!t) t = 1;else if(cur + (1ll << i) <= r) cur |= 1ll << i;}cout << abs((a ^ cur) - (b ^ cur)) << endl;
}