AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game

题目分析在代码注释里。

int main() {
#if defined LOCAL && !defined DUIPAI
  ifstream in("main.in");
  cin.rdbuf(in.rdbuf());
//  ofstream out("main.out");
//  cout.rdbuf(out.rdbuf());
#endif
  int n, q;
  scan(n, q);
  vi a(n);
  scan(a);
  vl sum(n);
  sum[0] = a[0];
  rng (i, 1, n) {
    sum[i] = a[i] + sum[i - 1];
  }
  vl parity_sum(n);
  parity_sum[0] = a[0];
  parity_sum[1] = a[1];
  rng (i, 2, n) {
    parity_sum[i] = a[i] + parity_sum[i - 2];
  }

  rep (q) {
    int x;
    scan(x);
    // 二分查找Aoki拿走的最大的数。
    // 设Aoki拿走的最大的数是a[i]。
    // 拿了a[i]之后,Aoki手里共有 i + 1 - LB(a, x - abs(x - a[i])) 个数。
    // 而此时Takahashi手里至多有n - i 个数,因此i必须满足i + 1 - LB(a, x - abs(x - a[i])) <= n - i
    int l = 0, r = n - 1;
    while (l + 1 < r) {
      bool flag = false;
      int mid = get_mid(l, r);
      int at_most = n - 1 - mid;
      auto t = LB(a, x - abs(x - a[mid]));
      int taken = mid - t + 1;
      if (taken <= at_most) {
        l = mid;
      } else {
        r = mid;
      }
    }
    ll ans = sum[n - 1] - sum[l];
    int num = n - 1 - l;
    if (n - 2 * num - 1 >= 0) {
      ans += parity_sum[n - 2 * num - 1];
    }
    println(ans);
  }
#if defined LOCAL && !defined DUIPAI
  cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
  return 0;
}

原文地址:https://www.cnblogs.com/Patt/p/12063513.html

时间: 2024-10-29 20:03:22

AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game的相关文章

[AtCoder] NIKKEI Programming Contest 2019 (暂缺F)

[AtCoder] NIKKEI Programming Contest 2019 ??本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder. A - Subscribers ??首先始终 \(max = \min(A, B)\) ,\(min\) 的话如果 \(A + B \leq N\) ,那么就是 \(0\) ,否则就是 \(A + B - N\) . int n, a, b; int main() { read(n), read

【AtCoder】AISing Programming Contest 2019

本来以为是1199rated的..仔细一看发现是1999,所以就做了一下 这场涨分很轻松啊...为啥又没打 等pkuwc考完我一定打一场atcoder(咕咕咕,咕咕咕,咕咕咕咕咕咕咕~) 但是其实我思维速度上真的有点不行... A - Bulletin Board 输出\((N - W + 1)(N - H + 1)\) #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int

AtCoder NIKKEI Programming Contest 2019 C. Different Strokes (贪心)

题目链接:https://nikkei2019-qual.contest.atcoder.jp/tasks/nikkei2019_qual_C 题意:给出 n 种食物,Takahashi 吃下获得 ai 快乐值,Aoki 吃下获得 bi 快乐值,两人轮流吃,他们的目标是最大化自己获得的快乐值减去她人获得的快乐值吗,问最后该值是多少. 题解:易知 Takahashi 要最大化答案而 Aoki 要最小化答案,考虑全部食物由 Aoki 吃下,则ans = -(b1 + b2 + .... + bn),

Atcoder Yahoo Programming Contest 2019 简要题解

A-C 直接放代码吧. A int n,k; int main() { n=read();k=read(); puts(k<=(n+1)/2?"YES":"NO"); return 0; } B int d[N];pair<int,int>s[10]; int main() { for(int i=1,u,v;i<=3;i++){ u=read();v=read(); s[i].first=u;s[i].second=v; d[u]++;d[

atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges

题目链接:Weights on Vertices and Edges 题目大意:有一个\(n\)个点\(m\)条边的无向图,点有点权,边有边权,问至少删去多少条边使得对于剩下的每一条边,它所在的联通块的点权值和大于等于该边的边权 其实是蛮简单的一道题目,为什么当时就自闭了呢... 正向删边明显不靠谱,于是我们考虑反向加边,答案就是\(m-\)加入的边数 我们按照边权排序,使用并查集维护点权值和,同时记录一个\(cnt\)数组表示当前存在于该联通块内但未加入答案的边数 如果说当前联通块的点权值和大

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

【AtCoder】全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

感觉最近好颓,以后不能这么颓了,要省选了,争取省选之前再板刷一面ATC??? A - Subscribers 简单容斥 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n')

NIKKEI Programming Contest 2019 翻车记

A:签到. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getc

Yahoo Programming Contest 2019

A - Anti-Adjacency 签. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 int n, k; 7 while (scanf("%d%d", &n, &k) != EOF) 8 { 9 int remind = (n + 1) / 2; 10 puts(k <= remind ? "YES" : "NO"