首页 > 其他分享 >Educational Codeforces Round 161 (Rated for Div. 2)

Educational Codeforces Round 161 (Rated for Div. 2)

时间:2024-01-19 17:36:27浏览次数:31  
标签:Educational Rated 数列 int Codeforces kN read ch getchar

目录

写在前面

比赛地址:https://codeforces.com/contest/1922

D 没调出来亏炸了,第一次体验赛后五分钟过题的快感。

痛苦的大二上终于结束了,本学期一半的痛苦都来自于傻逼大物实验。

下学期课少了好多,而且早八和晚八都少的一批,集中上一波分了就。

A

题面太长不看怒吃两发呃呃

分别考虑每个位置,当 \(a_i = c_i\) 或 \(b_i = c_i\) 时该位置必定不合法。当且仅当所有位置均不合法时无解。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    std::string a, b, c, d;
    int flag = 1, n;
    std::cin >> n >> a >> b >> c;
    for (int i = 0; i < n; ++ i) {
      if (a[i] == c[i] || b[i] == c[i]) continue;
      flag = 0;
    }
    printf("%s\n", (flag == 0) ? "YES" : "NO");
  }
  return 0;
}

B

典中典之 \(2^{i - 1} + 2^{i - 1} = 2^i\),则组成的三角形合法当且仅当等边,或者等腰且底比腰短

组合数搞下就好了。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 3e5 + 10;
//=============================================================
int n, a[kN], cnt[kN];
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
LL C2(int x_) {
  if (x_ < 2) return 0;
  return 1ll * x_ * (x_ - 1) / 2ll;
}
LL C3(int x_) {
  if (x_ < 3) return 0;
  return 1ll * x_ * (x_ - 1) / 2ll * (x_ - 2) / 3ll;
}
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    n = read();
    for (int i = 0; i <= n; ++ i) cnt[i] = 0;
    for (int i = 1; i <= n; ++ i) {
      a[i] = read();
      cnt[a[i]] ++;
    }

    LL ans = 0;
    int num = 0;
    for (int i = 0; i <= n; ++ i) {
      ans += C3(cnt[i]);
      ans += num * C2(cnt[i]);
      num += cnt[i];
    }
    printf("%lld\n", ans);
  }
  return 0;
}

C

不懂为啥这题有个贪心的标签。

对于一次询问显然只会在相邻城市之间移动,仅需求一路上可以减小的代价之和即可。则对于任意询问 \(x<y\),记 \(\operatorname{sum0}(i)\) 表示从城市 1 移动到城市 \(i + 1\) 一路上可以用第二种旅行减小的代价之和,答案即为 \(a_y - a_x - \operatorname{sum0}(y - 1) - \operatorname{sum0}(x - 1)\)。\(x > y\) 的询问同理,预处理 \(\operatorname{sum1}(i)\) 表示从城市 \(n\) 移动到城市 \(i - 1\) 一路上可以用第二种旅行减小的代价之和即可。

求每个城市的最近城市预处理即可,总时空复杂度 \(O(n + m)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 1e5 + 10;
const LL kInf = 2e9 + 2077;
//=============================================================
int n, m;
LL a[kN], sum[2][kN];
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
void Init() {
  n = read();
  a[0] = -kInf, a[n + 1] = kInf;
  sum[0][0] = sum[1][n + 1] = 0;
  for (int i = 1; i <= n; ++ i) a[i] = read(), sum[0][i] = sum[1][i] = 0;
  for (int i = 1; i <= n; ++ i) {
    LL d1 = a[i] - a[i - 1], d2 = a[i + 1] - a[i];
    sum[0][i] = sum[1][i] = 0;
    if (d1 < d2) {
      sum[1][i] = -d1 + 1;
    } else {
      sum[0][i] = -d2 + 1;
    }
  }

  for (int i = 1; i <= n; ++ i) sum[0][i] += sum[0][i - 1];
  for (int i = n; i >= 1; -- i) sum[1][i] += sum[1][i + 1];
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    Init();
    int m = read();
    while (m --) {
      int x = read(), y = read();
      LL ans = abs(a[x] - a[y]);
      if (x < y) {
        ans += sum[0][y - 1] - sum[0][x - 1];
      } else {
        ans += sum[1][y + 1] - sum[1][x + 1];
      }
      printf("%lld\n", ans);
    }
  }
  return 0;
}

D

没调出来妈的,赛后五分钟发现是偷懒直接用置零 \(a_i\) 表示把 \(i\) 杀了影响到同一轮其他的判断了呃呃,我是飞舞一个好相似、、、

发现当某一轮没有怪物挂掉则之后也不会有任何怪物挂掉;对于每一轮游戏,有可能会挂掉的怪物尽可能是在上一轮挂掉的怪物两侧的怪物。于是直接模拟给定的过程,用链表维护相邻的怪物,并且每一轮仅需考虑在上一轮中挂掉的怪物相邻的怪物即可。

注意某一轮没有怪物挂掉则停止模拟并输出若干个 0。另外注意写法,由规则可知需要在判断完所有怪物是否似掉之后才能修改链表,求下一轮影响到的怪物之前要更新完链表。

总时间复杂度 \(O(n)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 3e5 + 10;
//=============================================================
int n, a[kN], d[kN], dead[kN];
int pre[kN], next[kN];
//=============================================================
inline int read() {
  int f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0'); 
  return f * w;
}
void Solve() {
  std::queue <int> q1, q2, q3;
  int len = 0;
  for (int i = 1; i <= n; ++ i) q1.push(i);
  for (int i = 1; i <= n; ++ i) {
    int ans = 0;
    while (!q1.empty()) {
      int x = q1.front(); q1.pop();
      if (dead[x] || x <= 0 || x > n) continue;
      if (d[x] < a[pre[x]] + a[next[x]]) {
        if (!dead[x]) ++ ans, dead[x] = 1;
        q2.push(x);
      }
    }
    printf("%d ", ans);
    ++ len;
    if (ans == 0) break;

    while (!q2.empty()) {
      int x = q2.front(); q2.pop();
      q3.push(x);
      next[pre[x]] = next[x];
      pre[next[x]] = pre[x];
    }
    while (!q3.empty()) {
      int x = q3.front(); q3.pop();
      q1.push(pre[x]), q1.push(next[x]);
    }
  }
  for (int i = len + 1; i <= n; ++ i) printf("0 ");
  printf("\n");
}
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    n = read();
    a[0] = a[n + 1] = 0;
    d[0] = d[n + 1] = 0;
    for (int i = 1; i <= n; ++ i) a[i] = read();
    for (int i = 1; i <= n; ++ i) {
      dead[i] = 0;
      pre[i] = i - 1, next[i] = i + 1;
    }
    for (int i = 1; i <= n; ++ i) d[i] = read();
    Solve();
  }
  return 0;
}

E

好玩构造,一开始写了个上限是 900 个数的直接硬吃两发,然后莫名其妙地手玩了下直接出来了,最人类智慧的一集。

首先发现一个长度为 \(n\) 的递增数列中有 \(2^{n}\) 个递增子数列(含空数列),于是想到能不能二进制分解 \(X\)。

一开始的想法是发现有两个递增数列 \(a_1\sim a_n\) 和 \(b_1\sim b_m\),且满足 \(a_1>b_m\),则数列 \(a_1\sim a_n, b_1\sim b_m\) 中递增子数列数量即为 \((2^{n} - 1) + (2^{m} - 1) + 1\),于是考虑用 \(2^{x} - 1\) 凑 \(X-1\),然而这样搞所需数量上限为 \(\sum_{i=1}^{\log_2 X} i \approx 10^3\),过不去呃呃吃了三发

于是开始手玩。一个思考方向是为了最小化所需数量至少要有一个长度为 \(\left\lfloor\log_2 X\right\rfloor\) 的递增数列,考虑能否复用这个递增数列中的某些元素来凑出其他 2 的幂出来。发现可以通过在左侧添加一些数来满足上述要求。比如:1 2 3 4 有 \(2^4\) 个递增子数列,1 1 2 3 4 有 \(2^4 + 2^3\) 个递增子数列,2 1 2 3 4 有 \(2^4 + 2^2\) 个递增子数列,2 1 1 2 3 4 有 \(2^4 + 2^3 + 2^2\) 个递增子数列。

通过上面的例子,构造方案已经呼之欲出了。具体地:首先构造递增数数列 \(0, 1, \cdots, \left\lfloor \log_2 X \right\rfloor - 1\),对 \(X\) 进行二进制分解后从高位到低位枚举,若第 \(i(0\le i<\log_2 X)\) 位为 1 则在数列最左侧添加 \(\left\lfloor \log_2 X \right\rfloor - 1 - i\)。该构造方案至多需要 \(2\times \left\lfloor \log_2 X \right\rfloor - 1 \le 120\) 个数,所以不会出现无解的情况。


F

看着像好玩 DP,之后补一下。

写在最后

学到了什么:

  • B:虽然这题不会溢出……求 \(C(x, 3)\) 的时候最好写成 1ll * x_ * (x_ - 1) / 2ll * (x_ - 2) / 3ll
  • D:发现每轮会发生改变的元素有限,且总数是确定的,则仅需考虑总复杂度并且每轮对会发生改变的元素进行操作即可。
  • E:发现数量与 2 的幂有关考虑二进制分解。

标签:Educational,Rated,数列,int,Codeforces,kN,read,ch,getchar
From: https://www.cnblogs.com/luckyblock/p/17975162

相关文章

  • Codeforces 920 (div3)
    Problem-A-Codeforces没什么问题,几个ifelse语句,判断一下条件;#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;intmain(){intk;cin>>k;while(k--){intx1,y1,x2,y2,x3,y3,x4,y4;......
  • Codeforces edu 161 (div2)
    Problem-A-Codeforces思维题,判断c字符串的每一位是否都能在相对应的a字符串或者b字符串里面找到;如果都能找到的话就输出NO;否则输出YES;#include<bits/stdc++.h>usingnamespacestd;intmain(){std::ios::sync_with_stdio(false);cin.tie(0);cout.tie......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    EducationalCodeforcesRound161(RatedforDiv.2)比赛链接A.TrickyTemplate思路:貌似只要想到了就可以,我是记录了一下字符串c和字符串a和b之间的满足数,如果等于n表示一定不存在,否则就是存在的Code:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglon......
  • CodeForces & AtCoder rating 规则简述
    译者:rui_er,转载请注明出处。(备份自2020年11月2日的同名博客)本博客为了方便自己查阅,同时也方便大家了解,但因为我英语很菜,所以难免有翻译错的地方,还请评论区纠正。未注明资料来源的均为常识积累。1CodeForcesrating规则1.1CodeForcesrating与名字颜色换算设\(r\)......
  • hey_left 8 Codeforces Round 871 (Div. 4)
    题目链接A.直接比较输入字符串和已知字符串有几个不同即可#include<bits/stdc++.h>usingnamespacestd;voidsolve(){strings;cin>>s;intans=0;stringt="codeforces";for(inti=0;i<10;i++){if(s[i]!=t[i])ans++;}cout<&......
  • hey_left 7 Codeforces Round 886 (Div. 4) 续
    题目链接F.记录下出现的数字和个数注意放置陷阱的位置1-n都有可能然后遍历1-n,对每个数进行因子分解,对于在因子的位置上有青蛙的,加上青蛙的个数,取最大即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=2e5+10;voidsolve(){int......
  • CodeForces 1466H Finding satisfactory solutions
    洛谷传送门CF传送门考虑给定\(b\)如何构造\(a\)。拎出基环树的环部分,把这些点连同它们的边删掉(这个环一定在答案中)。递归做即可。考虑我们在\(a\)的环上连一些在\(\{b_{i,n}\}\)中排得比\(a_i\)前的\(i\toj\)。可以将问题转化为,若干个环,缩点后连一些边使得它成......
  • hey_left 6 Codeforces Round 886 (Div. 4)
    题目链接A.判总和-最小值的差是否大等于10即可#include<bits/stdc++.h>usingnamespacestd;constintN=2e5+10;voidsolve(){inta,b,c;cin>>a>>b>>c;intans=a+b+c;ans-=min({a,b,c});if(ans>=10){cout<<"YES&qu......
  • CodeForces 986F Oppa Funcan Style Remastered
    洛谷传送门CF传送门有意思的。对\(k\)分解质因数,题目实际上是想让我们解一个\(\sum\limits_{i=1}^ma_ix_i=n\)的方程。考虑\(m=1\)特判,\(m=2\)exgcd。\(m=3\)时发现\(\min\limits_{i=1}^ma_i\lek^{\frac{1}{3}}\le10^5\),所以可以跑同余最短路。......
  • CodeForces 814E An unavoidable detour for home
    洛谷传送门CF传送门考虑给图分层,一层的点一一对应上一层的一些点。设\(f_{i,j}\)为考虑了前\(i\)个点,最后一层有\(j\)个点,除了最后一层点的其他点度数限制已经满足的方案数。转移系数是\(g_{i,j,k}\)表示这一层有\(i\)个点,上一层有\(j\)个\(2\)度点,\(k\)个......