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

Educational Codeforces Round 171 (Rated for Div. 2)

时间:2024-10-29 11:11:21浏览次数:7  
标签:std Educational Rated int LL Codeforces ret kN dep

目录

写在前面

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

因为太困了决定睡大觉,于是赛时 unrated register 只写了 DE。

然而十一点半上床还是失眠到一点半睡的太搞了呃呃

A 签到

B 暴力

限定了只能操作白色格子,显然对于 \(n\) 为偶数只能直接操作,\(n\) 为奇数一定会多操作一个格子。

一个显然的结论是,对于 \(n\) 为奇数的情况,多操作的格子的位置一定为某个 \(a_i\) 前驱或后继(即 \(a_i + 1\) 或 \(a_i - 1\))。

这等价于删去某个位置(即与多修改的格子匹配的位置)之后,求前面所有位置的差分,以及后面所有位置的差分的最大值。要是不注意数据范围的话可能就会去写这个 \(O(n)\) 的东西了。

然而 \(O(n^2)\) 可过,于是直接枚举修改位置即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2010;
//=============================================================
int n;
LL a[kN];
//=============================================================
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    std::cin >> n;
    LL ans = 0;
    for (int i = 1; i <= n; ++ i) std::cin >> a[i];
    if (n % 2 == 0) {
      for (int i = 2; i <= n; i += 2) ans = std::max(ans, a[i] - a[i - 1]); 
    
    } else {
      ans = a[n];
      std::set<LL> s;
      for (int i = 1; i <= n; ++ i) s.insert(a[i] - 1), s.insert(a[i] + 1);
      for (auto p: s) {
        std::vector<LL> b;
        for (int i = 1; i <= n; ++ i) if (a[i] < p) b.push_back(a[i]);
        b.push_back(p);
        for (int i = 1; i <= n; ++ i) if (a[i] > p) b.push_back(a[i]);
        
        LL k = 0;
        for (int i = 1; i <= n; i += 2) k = std::max(k, b[i] - b[i - 1]);
        ans = std::min(ans, k);
      }
    
    }
    std::cout << ans << "\n";
  }
  return 0;
}

C 反悔贪心

D 枚举,分块,推式子

经典题,写了一个类似分块的做法。

考虑按照 \(s(l, r)\) 的左端点 \(l\) 对构造的数列 \(b\) 分块,每次询问分别处理左右的散块和中间的整块。

对于中间的整块考虑预处理,记:\(\operatorname{sum}_i\) 表示 \(a\) 的前缀和,\(\operatorname{sum}'_i\) 表示 \(a\) 的二维前缀和,记 \(S_{i} = \sum_{i\le j\le n} s(i, j)\) 表示整块的和。\(S_1\) 即 \(\operatorname{sum}'_n\),且显然可以递推:

\[S_i = S_{i - 1} - (n - i + 2)\times a_{i - 1} \]

再对 \(S\) 做个前缀和即可快速询问整块的和。

对于左右散块推下式子,记当前位于块 \(\operatorname{id}\),且 \(l, r\) 分别为该块的第 \(l', r'\) 个元素,则有:

\[\sum_{l'\le j\le r'} s(\operatorname{id}, j) = \operatorname{sum}'_{\operatorname{id} + r' - 1} - \operatorname{sum}'_{\operatorname{id} + l' - 2} - (r - l + 1)\times \operatorname{sum}_{\operatorname{id} - 1} \]

每次找到端点所在块使用二分,总时间复杂度 \(O(n + q\log n)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 3e5 + 10;
//=============================================================
int n, a[kN];
LL L[kN], R[kN], sum[kN], sumsum[kN];
LL S[kN], sumS[kN];
//=============================================================
int get(LL pos_) {
  int ret = 1;
  for (int l = 1, r = n; l <= r; ) {
    int mid = (l + r) >> 1;
    if (pos_ >= L[mid]) {
      ret = mid;
      l = mid + 1;
    } else {
      r = mid - 1;
    }
  }
  return ret;
}
LL query(LL l_, LL r_) {
  int bl = get(l_), br = get(r_);
  LL ret = 0;
  if (bl == br) {
    int pl = l_ - L[bl] + 1, pr = r_ - L[bl] + 1, len = r_ - l_ + 1;
    ret = sumsum[bl + pr - 1] - sumsum[bl + pl - 1 - 1] - len * sum[bl - 1];
  } else {
    ret = sumS[br - 1] - sumS[bl];
    ret += query(l_, R[bl]) + query(L[br], r_);
  }
  return ret;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  std::cin >> n;
  for (int i = 1; i <= n; ++ i) std::cin >> a[i];
  for (int i = 1; i <= n; ++ i) sum[i] = sum[i - 1] + a[i];
  for (int i = 1; i <= n + 1; ++ i) L[i] = R[i - 1] + 1, R[i] = R[i - 1] + (n - i + 1);
  
  for (int i = 1; i <= n; ++ i) sumsum[i] = sumsum[i - 1] + sum[i];
  S[1] = sumsum[n];
  for (int i = 2; i <= n; ++ i) S[i] = S[i - 1] - (n - i + 2) * a[i - 1];
  for (int i = 1; i <= n; ++ i) sumS[i] = sumS[i - 1] + S[i];
  
  int q; std::cin >> q;
  while (q --) {
    LL l, r; std::cin >> l >> r;
    std::cout << query(l, r) << "\n";
  }
  return 0;
}

E 网络流,最大权闭合子图

一眼最大权闭合子图板子,具体做法和证明见这题:P2762 太空飞行计划问题

看不出来的鉴定为没写完网络流 24 题。

最搞的是调了二十分钟发现自己板子写错了哈哈。

//知识点:网络最大流,Dinic
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 1e5 + 10;
const int kM = 2e6 + 10;
const LL kInf = 1e18 + 2077;
//=============================================================
int n, m, k, S, T;
int nodenum, maxnodenum, edgenum = 1, v[kM], ne[kM], head[kN];
int cur[kN], dep[kN];
LL w[kM];
//=============================================================
void addedge(int u_, int v_, LL w_) {
  v[++ edgenum] = v_;
  w[edgenum] = w_;
  ne[edgenum] = head[u_];
  head[u_] = edgenum;

  v[++ edgenum] = u_;
  w[edgenum] = 0;
  ne[edgenum] = head[v_];
  head[v_] = edgenum;
}
void init() {
  std::cin >> n;
  
  edgenum = 1;
  nodenum = n + 61;
  maxnodenum = n + 100;
  S = ++ nodenum, T = ++ nodenum;
  
  for (int i = 1; i <= maxnodenum; ++ i) {
    head[i] = 0;
  }

  for (int i = 0; i < 60; ++ i) addedge(n + i + 1, T, 1);
  for (int i = 1; i <= n; ++ i) {
    LL a; std::cin >> a;
    addedge(S, i, 1);
    for (LL j = 0; j < 60; ++ j) {
      if (a >> j & 1ll) addedge(i, n + j + 1, kInf);
    }
  }
}
bool bfs() {
  std::queue <int> q;
  memset(dep, 0, (nodenum + 1) * sizeof (int));
  dep[S] = 1; //注意初始化 
  q.push(S); 
  while (!q.empty()) {
    int u_ = q.front(); q.pop();
    for (int i = head[u_]; i > 1; i = ne[i]) {
      int v_ = v[i];
      LL w_ = w[i];
      if (w_ > 0 && !dep[v_]) {
        dep[v_] = dep[u_] + 1;
        q.push(v_);
      }
    }
  }
  return dep[T];
}
LL dfs1(int u_, LL into_) {
  if (u_ == T) return into_; 
  LL ret = 0;
	for (int i = cur[u_]; i > 1 && into_; i = ne[i]) {
    int v_ = v[i];
    LL w_ = w[i];
    if (w_ && dep[v_] == dep[u_] + 1) {
			LL dist = dfs1(v_, std::min(into_, w_));
			if (!dist) dep[v_] = kN;
			into_ -= dist; 
      ret += dist;
      w[i] -= dist, w[i ^ 1] += dist;
			if (!into_) return ret;
		}
  }
	if (!ret) dep[u_] = 0; 
  return ret;
}
LL dinic() {
  LL ret = 0;
  while (bfs()) {
    memcpy(cur, head, (nodenum + 1) * sizeof (int));
    ret += dfs1(S, kInf);
  }
  return ret;
}
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    init();
    std::cout << n - dinic() << "\n";
  }
  return 0;
}

F

写在最后

zzz。

败犬女主真好看。

标签:std,Educational,Rated,int,LL,Codeforces,ret,kN,dep
From: https://www.cnblogs.com/luckyblock/p/18512564

相关文章

  • Educational Codeforces Round 171 (Rated for Div. 2)
    A.PerpendicularSegments分析题目中的要求\(34\),说明需要较短的线段尽量长,那么两个线段应该一样长而又要求线段垂直,那么两线段可以放在一个正方形内做对角线那么此时\(x\)和\(y\)对称(代数一样上),取两个的较小值做一个正方形,答案即为对角线#include<bits/stdc++.h>usin......
  • Codeforces Round 982 (Div. 2) 10.26 (ABC)题解
    CodeforcesRound982(Div.2)10.26(ABC)题解A.RectangleArrangement数学(math)题意:有一个无限长宽的方形网格,初始为白色,现在有\(n\)个印章,每个印章有自己的宽\(w_i\)和高\(h_i\)。印章会使得网格涂色,变成黑色。这\(n\)个印章都需要使用一次,需要求解出最后网格中黑色......
  • Codeforces Round 982 (Div. 2) 题解(A-D)
    目录A思路codeB思路codeC思路卡题原因codeD思路未ac原因codeCodeforcesRound982(Div.2)A思路因为图形可以重叠,所以答案就是最长的长和最长的宽组成的矩形周长.codevoidfunc(void){ intn; cin>>n; intl=0,r=0; while(n--) { intx,y; cin>>x>>y......
  • Codeforces Round 982 (Div. 2)
    A.RectangleArrangement题目给定\(n\)个矩形,\(n\)个矩形可以组成的图形(可以重叠)中,最小的周长的多少,矩形不能旋转,分析乍一看并没有什么思路,但是写出这个题并不能,案例很好的提示了我们要将所有矩形一角放一起,那么最后就会组成一个阶梯形状的图案,感觉割补法,这个图形周长等......
  • Codeforces Round 981 (Div. 3) 题解(A-E)
    目录分析A思路代码B思路卡题原因代码C思路卡题原因codeD思路卡题原因代码E思路wa原因codeCodeforcesRound981(Div.3)分析这场整体发挥都不好,虽然题也抽象,但是对于这些题完全没必要卡这么久.正常至少能看到\(\mathbf{F}\)A思路因为边界\(n\)管辖\(\pm\),而Sak......
  • Codeforces Round 980 (Div. 2) 题解(A-D)
    目录A思路B思路wa原因C思路wa原因代码D思路未ac原因代码CodeforcesRound980(Div.2)A思路推方程式即可,勉强算贪心吧.需要使得\({a-x}\)最小,那么\(x\)就需要最小,而满足题目条件,需要\(a-x\geb-2x\)得出\(x\geb-a\),又因为需要\(a\)最大,所以\(......
  • Python's exec Functions: Execute Dynamically Generated Code
      #encoding:utf-8#版權所有2024©塗聚文有限公司#許可資訊查看:言語成了邀功的功臣,還需要行爲每日來值班嗎?#描述:主、子表單窗體傳值Parent-childformoperations#Author:geovindu,GeovinDu塗聚文.#IDE:PyCharm2023.1python3.11#OS......
  • Codeforces Round 982 div2 个人题解(A~D2)
    CodeforcesRound982div2个人题解(A~D2)Dashboard-CodeforcesRound982(Div.2)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#include<cmath>#include<cstdio>#in......
  • Codeforces Round 980 (Div. 2)
    目录写在前面A签到B贪心,模拟C贪心,结论,思维D图论转化,最短路写在最后写在前面比赛地址:https://codeforces.com/contest/2030。赛时被B硬控1h,后面两题一眼秒了一共写了20min呃呃。还好是小号。A签到讨论一下很容易算出来最优决策。///*By:Luckyblock*/#include......
  • Codeforces Round 981 (Div. 3) 10.24 (ABCDE)题解
    CodeforcesRound981(Div.3)2024.10.24题解A.SakurakoandKosuke题意:\(Sakurako\)与\(Kosuke\)正在玩游戏,一个点在原点\(x=0\)的起始位置。对于第\(i\)次操作,点会移动\(2\asti-1\)步。两人轮流操作,Sakurako先手,每次将点往负方向移动;Kosuke每次将点往正方向移动......