在群友聊天下偷听到 nlogn ≈ 20n,我对nlogn有了更深的理解。
这是 log 1e5
——————
Dashboard - Codeforces Round 945 (Div. 2) - Codeforces
拖了很久做出AB,掉70分,暂时绝缘蓝名~
A
贪心
和本周四的力扣每日一题思路一样,而且我做过,结果赛时要想半个小时😭。
总结就是最大的要是能被其他的‘“对付掉”,那么全部都能完成。否则就对付最大的。
理解上:
最大的比其他的和还大,这个好理解。
相对的情况,可以这样理解:
可以把最大的数展开,1 1 1 1 1 1 ,每两个1中间都留了空位,别的数也展开,去插入这些空位。
不可否认,不管什么情况,对每一个数来说,都是绝对够插入的。
既然插入的是空位,那么就不存在相邻了;最大数的空位能够被占满,说明都能符合了。
B
赛时写了ST表来记录区间异或值,这样可以二进制拆分快速获得任意区间的异或值。(就是优化了暴力)
然后二分答案。
看了一些题解,是记录每个二进制位的前缀。
因为或完比较是否相等,比的也就是每一个二进制位。而每一位的话就可以用前缀和了。
都是 nlognlogA的
nlogA的解法:对于每个二进制位 ,在数组中出现的间隔的最大值
cv佬的:
void solve() {
int n; cin >> n;
vector<int> a(n + 1);
for(int i = 1; i <= n; i++) cin >> a[i];
int ans = 1;
for(int i = 0; i <= 25; i++)//# 看每个二进制位
{
vector<int> dis(1);//间隔包含0 n+1的位置,即首尾
for(int j = 1; j <= n; j++)//# 看哪个数中出现了
{
if(((a[j] >> i) & 1 )== 0) continue;
dis.push_back(j);
}
dis.push_back(n + 1);
if(dis.size() == 2) continue;
for(int j = 1; j < dis.size(); j++)//计算间隔
{
int temp = dis[j] - dis[j - 1];
ans = max(ans, temp);
}
}
cout << ans << endl;
}