首页 > 其他分享 >Codeforces Round 919 (Div. 2)

Codeforces Round 919 (Div. 2)

时间:2024-01-19 19:24:52浏览次数:32  
标签:ch int LL Codeforces kN read 919 Div getchar

目录

写在前面

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

考试周突然发癫想打 cf 但是觉得肯定打不完所以拿小号打的。

手速慢了没上大分呃呃

A

求出上下界来,再求被限制的数有多少个在区间内即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kInf = 1e9 + 2077;
//=============================================================
//=============================================================
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 --) {
    int minn = -kInf, maxx = kInf;
    std::map <int, bool> vis;
    int n = read();
    while (n --) {
      int opt = read();
      if (opt == 1) {
        minn = std::max(minn, read());
      } else if (opt == 2) {
        maxx = std::min(maxx, read());
      } else {
        vis[read()] = 1;
      }
    }

    int num = maxx - minn + 1;
    for (auto x: vis) {
      num -= (minn <= x.first && x.first <= maxx);
    }
    printf("%d\n", minn > maxx ? 0 : num);
  }
  return 0;
}

B

所有数均为正数,则当 Alice 确定了保留哪些数之后 Bob 的行动就确定了,一定会把其中最大的 \(k\) 个变成负数。

另外发现 Alice 保留的数一定是一段连续的前缀。考虑反证,若 Alice 保留的数按升序排序后是 \(a_1\sim a_{i-1}, a_{i + 1}\sim a_{m}\),若 \(k\le m - i\),则 Alice 少删一个 \(a_i\) 可以获得更大的价值;若 \(k\ge m-i\),则 Alice 把删 \(a_{i}\) 换成删 \(a_{m}\) 可以损失得更少。

则考虑枚举 Alice 保留的前缀长度,再减去 Bob 删的数的贡献,所有情况取最大值即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
const LL kInf = 1e15 + 2077;
//=============================================================
int n, k, x, a[kN];
LL sum[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;
}
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    n = read(), k = read(), x = read();
    for (int i = 1; i <= n; ++ i) a[i] = read();
    std::sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; ++ i) sum[i] = sum[i - 1] + a[i];
    // for (int i = n; i >= 1; -- i) sum[i] = sum[i + 1] + 1ll * a[i];

    LL ans = -kInf, s;
    for (int i = n, j = 0; i >= 0 && j <= k; -- i, ++ j) {
      s = sum[i];
      s -= 2ll * sum[i] - 2ll * sum[std::max(0, i - x)];
      ans = std::max(ans, s);
    }
    printf("%lld\n", ans);
  }
  return 0;
}

C

\(O(10^5)\) 的 \(n\) 的因子个数最多只有 128 个(https://oeis.org/A066150),于是考虑枚举每段的长度 \(k\),先考虑如何每段的同一个位置的数 \(\{a_i, a_{k + i}, a_{2\times k + i}\cdots\}\) 变为相同的数。对某个数 \(m\) 取模之后 \(\{a_i, a_{k + i}, a_{2\times k + i}\cdots\}\) 变为相同的数,即这些数模 \(m\) 均相等,说明这些数之间的差均是 \(m\) 的倍数,则考虑将这些数升序排序并求相邻数之差,将差取 \(\gcd\) 即为 \(m\) 可能的最大值,且这个数的所有因子均可作为 \(m\)。

于是得到了使每段中同一位置变为相同的最大值 \(m_1, m_2, \cdots, m_k\),由上述分析,再将这些数取 \(\gcd\) 即为满足题意的最大的 \(m\),若 \(\ge 2\) 则当前枚举的 \(k\) 对答案贡献为 1,否则为 0。

实际实现上并不需要显式地把每段同一位置的数分离出来排序后作差再求 gcd,仅需枚举数列中所有距离为 \(k\) 的数对作差并对差取 gcd 即可。

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

下面是赛时的麻烦写法、、、

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, ans, a[kN], b[kN], c[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;
}
int gcd(int x_, int y_) {
  return y_ ? gcd(y_, x_ % y_) : x_;
}
void Solve(int k_) {
  if (k_ == n) {
    ++ ans;
    return ;
  }
  int g = 0;
  for (int i = 1; i <= k_; ++ i) {
    int p = 0;
    for (int j = 0; j * k_ + i <= n; ++ j) {
      b[++ p] = a[j * k_ + i];
    }
    std::sort(b + 1, b + p + 1);
    for (int j = p; j > 1; -- j) b[j] -= b[j - 1];
    for (int j = 2; j <= p; ++ j) {
      if (b[j] == 0) continue;
      g = gcd(g, b[j]);
    }
  }
  ans += (g != 1);
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    ans = 0;

    n = read();
    for (int i = 1; i <= n; ++ i) a[i] = read();
    for (int i = 1, lim = sqrt(n); i <= lim; ++ i) {
      if (n % i) continue;
      Solve(i);
      if (i * i != n) Solve(n / i);
    }
    printf("%d\n", ans);
  }
  return 0;
}

D

挺一眼的递归分治题呃呃

在读入操作过程中计算此时数列的长度,若长度大于 \(10^{18}\) 则记为极大值。

操作 2 并不会生成新种类的权值,则所有询问实质上都可以对应到某次操作 1 上。于是考虑反向地撤销操作并减少数列的长度,设撤销后数列长度为 \(l\),枚举所有大于 \(l\) 的询问,若这次操作为 1 则该询问的值即为此次操作 1 增加的值;若这次操作为 2 则计算该询问在撤销后的数列对应的位置,留到之后的撤销中解决即可。

在撤销过程中,对询问维护大根堆即可实现。

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

注意维护数列长度时可能爆 LL,开 __int128

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define pr std::pair
#define mp std::make_pair
#define LL __int128
// #define LL long long
const int kN = 1e5 + 10;
const LL kInf = 1e18 + 2077;
//=============================================================
int n, q;
struct Data {
  int opt, x;
  LL nowl;
} a[kN];
int ans[kN];
//=============================================================
inline LL read() {
  LL f = 1, w = 0; char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) w = (w << 3ll) + (w << 1ll) + (ch ^ '0'); 
  return f * w;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  int T = read();
  while (T --) {
    n = read(), q = read();
    for (int i = 1; i <= n; ++ i) {
      a[i].opt = read(), a[i].x = read();
      if (a[i].opt == 2) {
        a[i].nowl = a[i - 1].nowl + (LL) a[i].x * a[i - 1].nowl;
      } else {
        a[i].nowl = a[i - 1].nowl + 1;
      } 
      if (a[i].nowl > kInf) a[i].nowl = kInf;
    }

    std::priority_queue <pr <LL, int> > query;
    for (int i = 1; i <= q; ++ i) query.push(mp(read(), i));
    for (int i = n; i; -- i) {
      while (!query.empty() && (query.top().first) > a[i - 1].nowl) {
        pr <LL, int> now = query.top(); query.pop();
        if (a[i].opt == 1) {
          ans[now.second] = a[i].x;
        } else {
          now.first = now.first % a[i - 1].nowl;
          if (now.first == 0) now.first = a[i - 1].nowl;
          query.push(now);
        }
      }
    }
    for (int i = 1; i <= q; ++ i) printf("%d ", ans[i]);
    printf("\n");
  }
  return 0;
}

E

吃个饭回来补。

写在最后

学到了什么:

  • C:余数相同的数作差后肯定是模数的倍数。一张非常经典的表格。

标签:ch,int,LL,Codeforces,kN,read,919,Div,getchar
From: https://www.cnblogs.com/luckyblock/p/17975418

相关文章

  • Codeforces Round 920 (Div. 3)
    A.Square#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ inta1,b1,a2,b2,a3,b3,a4,b4; cin>>a1>>b1>>a2>>b2>>a3>>b3>>a4>>b4; ints1,s2; if(a1==a2){ s1=abs(b1-b2); s2=abs(b3-b4); }e......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    题目链接:EducationalCodeforcesRound161(RatedforDiv.2) PS:A开的很快,B读个假题意,C又想歪了,导致E没时间写,最后十分钟开E思路对了但是没时间了,赛后很快过了。。。A.TrickyTemplate题意:定义模板串t与字符串s:1:如果模板串的某一项为小写字母,那么模板串与字符串的该......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    目录写在前面ABCDEF写在最后写在前面比赛地址:https://codeforces.com/contest/1922D没调出来亏炸了,第一次体验赛后五分钟过题的快感。痛苦的大二上终于结束了,本学期一半的痛苦都来自于傻逼大物实验。下学期课少了好多,而且早八和晚八都少的一批,集中上一波分了就。A题面太长......
  • 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\)。可以将问题转化为,若干个环,缩点后连一些边使得它成......