当前位置:   article > 正文

Codeforces Round 923 (Div. 3)

Codeforces Round 923 (Div. 3)

D. Find the Different Ones!

分析:如果[l,r]存在两个不相同的数,那么一定存在 ai != aj,且 j = i+1,即这两个数是相邻的。这样的话我们可以用前缀和预处理,然后找pre[j]>pre[l]。

正常从前往后遍历是O(n),我们还有q次查询,时间复杂度O(n2)会超时。因此我们用二分查找来进行查询,时间复杂度O(nlogn)

  1. int a[N], pre[N];//pre[i]表示,从a1->ai相邻不同的对数
  2. void solve() {
  3. //memset(pre, 0, sizeof pre);
  4. int n; cin >> n;
  5. rep(i, 1, n) cin >> a[i];
  6. rep(i, 2, n) {
  7. pre[i] = pre[i - 1] + (a[i] != a[i - 1]);
  8. }
  9. int q; cin >> q;
  10. while (q--) {
  11. int l, r; cin >> l >> r;
  12. //tans;
  13. //在pre[l,r]里二分找大于pre[l],
  14. //找到的第一个pre[k]>pre[l],说明有增加的对数,且为a[k-1]和a[k]
  15. int k = upper_bound(pre + 1 + l, pre + 1 + r, pre[l]) - pre;
  16. if (k > r) cout << -1 << " " << -1 << endl;
  17. else cout << k - 1 << " " << k << endl;
  18. }
  19. }

E. Klever Permutation

分析:假设一个数组a是k级排列,那么a里有n-k+1组,每组的和与其他组的和的差不大于1。

数组a = {a1,a2,a3,a4,a5,a6,...},

第一,假设k = 3,说明 |(ai+aj+ak) - (aj+ak+al)| <= 1 (ijkl是+1递增的),

等同于 |ai - al| <= 1,我们要控制好ai和al的差小于等于1就行(也就是ai比al大1,或者al比ai大1)。

第二,假设其中一组和为x,那么其他组的和只能为x或者x+1。

第三,只要在奇数位从小到大以k的间隔填入,在偶数位从大到小以k的间隔填入,就可以构造出符合题意的序列。

ps:做完这道题有一点点个人理解,我发现很多题都会在奇数和偶数上下文章。像这题的特点就是“对称性”(我便于自己理解所以这么叫),例如:ai,aj,ak,al的关键是ai和al的放置,有一点“对称”的感觉

  1. int a[N];
  2. void solve() {
  3. int n, k; cin >> n >> k;
  4. int f = 1;
  5. int b = n;
  6. for (int i = 1; i <= k; i++) {
  7. if (i % 2) {
  8. for (int j = i; j <= n; j += k) a[j] = f++;
  9. }
  10. else {
  11. for (int j = i; j <= n; j += k) a[j] = b--;
  12. }
  13. }
  14. //tans;
  15. for (int i = 1; i <= n; i++) {
  16. cout << a[i] << " ";
  17. }
  18. cout << endl;
  19. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/102201
推荐阅读
相关标签
  

闽ICP备14008679号