CF1108A. Two distinct points

做法:模拟

如果两者左端点重合就第二条的左端点++就好,然后输出左端点

#include <bits/stdc++.h>
using namespace std;int T;
int l1, r1, l2, r2;int main() {scanf("%d", &T);while(T--) {scanf("%d%d%d%d", &l1, &r1, &l2, &r2);printf("%d ", l1);if(l1 == l2) l2++;printf("%d\n", l2);}
}

CF1108B. Divisors of Two Integers

做法:模拟

坑点好多...首先因为所有因数都有,所以最大的数一定是x,y中的一个.把它拎出来,然后删掉它的因子,剩下的最大的就是x,y中的另外一个了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;int n;
int a[100000];
int cnt[101000];int main() {scanf("%d", &n);int mx = 0;for(int i = 1; i <= n; ++i) {scanf("%d", &a[i]);cnt[a[i]]++;mx = max(mx, a[i]);}printf("%d ", mx);for(int i = 1; i * i <= mx; ++i) {if(mx % i == 0) {cnt[i]--;if(mx / i != i) cnt[mx / i]--;}}int ans = 0;for(int i = 1; i <= mx; ++i) {if(cnt[i] > 0) ans = i;}printf("%d\n", ans);
}

CF1108C. Nice Garland

做法:模拟

依旧是模拟qwq.显然合法的排列方式也就那么6种...于是6种方式都跑一遍,然后取min即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;int n, id = 0;
char s[N];
string f[6] = {"RGB", "RBG", "BRG", "BGR", "GRB", "GBR"};
int main() {scanf("%d%s", &n, s + 1);int ans = N;for(int k = 0; k < 6; ++k) {int sum = 0, pos = 0;for(int i = 1; i <= n; ++i, pos = (pos + 1) % 3) {if(s[i] != f[k][pos]) ++sum;}if(sum < ans) {ans = sum;id = k;}}printf("%d\n", ans);for(int i = 1, pos = 0; i <= n; ++i, pos = (pos + 1) % 3) putchar(f[id][pos]);
}

CF1108D. Diverse Garland

做法:dp

第一问显然sb dp,设f[i,j]表示点i然后点i填的是RGB中的一个(分别对应一个j),直接转移即可.输出方案反而比较难,有各种方法,我的方法是记录每个dp值的转移点,从后往前推回去.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;int n, id = 0;
char s[N], p[3] = {'R', 'G', 'B'};
int f[N][3], to[N][3];
char t[N];int main() {scanf("%d%s", &n, s + 1);memset(f, 0x3f, sizeof(f));f[1][0] = f[1][1] = f[1][2] = 1;if(s[1] == 'R') f[1][0] = 0;else if(s[1] == 'G') f[1][1] = 0;else f[1][2] = 0;for(int i = 2; i <= n; ++i) for(int j = 0; j < 3; ++j) for(int k = 0; k < 3; ++k) {if(j == k) continue; if(p[j] == s[i]) {if(f[i - 1][k] < f[i][j]) f[i][j] = f[i - 1][k], to[i][j] = k;} else {if(f[i - 1][k] + 1 < f[i][j]) f[i][j] = f[i - 1][k] + 1, to[i][j] = k;}}int ans = 0, id = 0;if(f[n][0] > f[n][1]) {ans = f[n][1], id = 1;} else ans = f[n][0], id = 0;if(f[n][2] < ans) ans = f[n][2], id = 2;printf("%d\n", ans);for(int i = n; i; i--) {t[i] = p[id];id = to[i][id];}for(int i = 1; i <= n; ++i) putchar(t[i]); puts("");return 0;
}

CF1108E1. Array and Segments (Easy version)

做法:暴力

考虑怎么样才能让结果最大,把线段分成两类,一种是没有覆盖最大值,一种是有覆盖最大值的,如果选了覆盖最大值的显然只会减小答案,所以可以暴力枚举最大值,并累加不覆盖最大值的线段,对所有情况取max即可复杂度是\(O(n^2m)\)的

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
const int inf = 0x3f3f3f3f;int n, m, a[N], b[N];
int vis[N];
struct seg {int l, r, id;
} s[N];
vector<int> Ans;
int ans = -1;int main() {scanf("%d%d", &n, &m);for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);for(int i = 1; i <= m; ++i) scanf("%d%d", &s[i].l, &s[i].r), s[i].id = i;for(int i = 1; i <= n; ++i) {vector<int> cur; cur.clear();int lans = 0;for(int j = 1; j <= n; ++j) b[j] = a[j];for(int j = 1; j <= m; ++j) {if(s[j].l <= i && i <= s[j].r) continue;for(int k = s[j].l; k <= s[j].r; ++k) b[k]--;cur.push_back(j);}for(int j = 1; j <= n; ++j) {if(j == i) continue;lans = max(lans, a[i] - b[j]);}if(lans > ans) {ans = lans;Ans = cur;}}sort(Ans.begin(), Ans.end());printf("%d\n%d\n", ans, (int)Ans.size());for(int i = 0, len = Ans.size(); i < len; ++i) {printf("%d ", Ans[i]);}return 0;
} 

CF1108E2. Array and Segments (Hard version)

做法:线段树优化暴力

考虑优化E1的暴力,注意到m很小,所以复杂度里面是可以有一个m的.然后利用线段树来优化把线段覆盖下去的过程,即利用线段树维护区间修改,维护区间min.这样的复杂度是\(O(nmlogn)\)的.这样朴素的去做会TLE on 12.发现每次如果加入线段然后再删除线段会有很多重复的操作,可以拿一个数组来标记哪条线段有覆盖哪条没有,如果有线段不能覆盖下去且已经覆盖了,那么就+1回去,能覆盖下去的同理,这样修改次数就大大降低了.这样就能通过本题了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int inf = 0x3f3f3f3f;int n, m, a[N], b[N];
struct seg {int l, r, id;
} s[N];
vector<int> Ans;
int ans = -1;struct tree {int l, r, mn, tag;
} t[N<<2];#define lc (rt << 1)
#define rc (rt << 1 | 1)
void pushup(int rt) { t[rt].mn = min(t[lc].mn, t[rc].mn); }
void build(int l, int r, int rt) {t[rt].l = l; t[rt].r = r; t[rt].mn = inf;if(l == r) { t[rt].mn = a[l]; return; }int mid = (l + r) >> 1;build(l, mid, lc); build(mid + 1, r, rc); pushup(rt);
}
void pushdown(int rt) {if(t[rt].tag) {int &x = t[rt].tag;t[lc].tag += x; t[rc].tag += x;t[lc].mn += x; t[rc].mn += x;x = 0;}
}
#define l (t[rt].l)
#define r (t[rt].r)
void upd(int L, int R, int c, int rt) {if(L <= l && r <= R) {t[rt].tag += c; t[rt].mn += c;return;}pushdown(rt); int mid = (l + r) >> 1;if(L <= mid) upd(L, R, c, lc); if(R > mid) upd(L, R, c, rc); pushup(rt);
}
#undef l
#undef r
#undef lc
#undef rcbool vis[N];int main() {scanf("%d%d", &n, &m);for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);for(int i = 1; i <= m; ++i) scanf("%d%d", &s[i].l, &s[i].r), s[i].id = i;build(1, n, 1);for(int i = 1; i <= n; ++i) {vector<int> cur; cur.clear();int lans = 0;for(int j = 1; j <= m; ++j) {if(s[j].l <= i && i <= s[j].r) {if(vis[j]) {vis[j] = 0;upd(s[j].l, s[j].r, 1, 1);}} else {if(!vis[j]) vis[j] = 1, upd(s[j].l, s[j].r, -1, 1);cur.push_back(j);}}lans = max(0, a[i] - t[1].mn);if(lans > ans) {ans = lans;Ans = cur;}}sort(Ans.begin(), Ans.end());printf("%d\n%d\n", ans, (int)Ans.size());for(int i = 0, len = Ans.size(); i < len; ++i) {printf("%d ", Ans[i]);}return 0;
} 

CF1108F. MST Unification

做法:最小生成树

考虑怎么样才会使一个最小生成树不唯一.设有一条边边权为val,且它没有在最小生成树中,那么加入最小生成树之后,就会出来一个环,如果这个环中有一条边边权为val,那么这个mst就是不唯一的.可以倍增实现这个过程但是比较麻烦,也可以选择就是对所有边权相同的边权统一考虑一下:如果此边的两个端点已经在最小生成树里面了,那么显然这条边对mst的唯一性没有影响(因为连接它的边边权一定更小),不用管它.如果两端点之前还未接入最小生成树,但是在加到这条边的时候又已经加入了(即有同样长度的边使两端点联通),那么这条边就一定会对答案产生影响,需要+1保证mst的唯一性

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;struct edge {int x, y, v;
} e[N];
int n, m, f[N];bool cmp(edge a, edge b) {return a.v < b.v;
}int find(int x) {if(f[x] == x) return x;else return f[x] = find(f[x]);
}int main() {scanf("%d%d", &n, &m);for(int i = 1; i <= m; ++i) {scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].v);}sort(e + 1, e + m + 1, cmp);for(int i = 1; i <= n; ++i) f[i] = i;int ans = 0;for(int i = 1, j = 1; i <= m; i = j) {while(j <= m && e[j].v == e[i].v) ++j;int tot = j - i;for(int k = i; k < j; ++k) {int x = find(e[k].x), y = find(e[k].y);if(x == y) --tot;}for(int k = i; k < j; ++k) {int x = find(e[k].x), y = find(e[k].y);if(x == y) continue;f[x] = y;--tot;}ans += tot;}printf("%d\n", ans);
}

转载于:https://www.cnblogs.com/henry-1202/p/10356234.html

Codeforces Round #535 (Div. 3) 解题报告相关推荐

  1. CodeCraft-19 and Codeforces Round #537 (Div. 2)解题报告

    Codeforces Round #537 (Div. 2) 题解报告 A. Superhero Transformation 题意 问能否通过把辅音字母换成另一个辅音字母,元音字母换成另一个元音字母 ...

  2. Codeforces Round #702 (Div. 3)解题报告

    Codeforces Round #702 (Div. 3) 全部题解 读错题意,写了半天真是心态爆炸,总的来看这次题目不难的. A. Dense Array http://codeforces.co ...

  3. Codeforces Round #264 (Div. 2) 解题报告

    Source:  http://codeforces.com/contest/463 打得比较差..第三题想写nlgn的,结果调了很久又wa,以为写挫,过了很久发现做法有问题..最后两题惨淡收场.第四 ...

  4. Codeforces Round #219 (Div. 2) 解题报告

    Problem A Collecting Beats is Fun 题意:就是音乐游戏在4*4的网上一些格子需要在固定的时间点,告诉你一只手同一时间能点几个.问你能不能通关(就是一个不丢) 思路:水题 ...

  5. Codeforces Round #535 (Div. 3) [codeforces div3 难度测评]

    hhhh感觉我真的太久没有接触过OI了 大约是前天听到JK他们约着一起刷codeforces,假期里觉得有些颓废的我忽然也心血来潮来看看题目 今天看codeforces才知道居然有div3了,感觉应该 ...

  6. Codeforces Round #578 (Div. 2) 题解报告

    A. Hotelier sb模拟,直接按题意模拟就可以了. B. Block Adventure Gildong is playing a video game called Block Advent ...

  7. Codeforces Round #535 (Div. 3)题解

    A. TwodistinctpointsTwo\ distinct\ pointsTwo distinct points 题目大意就是给出两个区间的左右边界,输出两个数,满足两个数分别在两个区间内且这 ...

  8. BestCoder Round #77 (div.2)解题报告

    昨晚和Yveh合作的成果-- T1 传送门 题意:给一个正整数集合,求集合中各个子集里各元素的总异或 思路:对于一个数x对自己异或的结果,异或偶数次是x,奇数次为0,而且一个集合的非空子集数目为2n− ...

  9. Codeforces Round #700 (Div. 2)A~D2解题报告

    Codeforces Round #700 (Div. 2)A~D2解题报告 A Yet Another String Game 原题链接 http://codeforces.com/contest/ ...

最新文章

  1. Lesson 6.1 身份证识别: 提取字段
  2. 网站收录慢的如“蜗牛”,是什么原因导致的?
  3. 【AI白身境】学AI必备的python基础
  4. 安装DNN时可能出现的错误
  5. 烧写linux内核的步骤,启动redboot后,向目标机烧写一个linux内核的全过程
  6. 索引-python编程技术-第二版
  7. asp.net MVC学习的一些总结
  8. vue-cli 里axios的使用
  9. 连线杂志:史上最强的恶意软件Stuxnet揭秘
  10. Microsoft SQL Server 2008 (RTM) 升级到 Microsoft SQL Server 2008 R2
  11. Linux使用命令行工具管理用户和组
  12. Excel之VBA简单宏编程
  13. 如何运行element ui
  14. Alsa 调试下篇:应用篇
  15. android程序填空题,10道android填空题及答案
  16. 基于李雅普诺夫函数的跟踪控制(三)
  17. 企业微信周末加班怎么打卡?
  18. 加速及控制精灵移动,加速计值的处理
  19. 什么叫虚继承(虚拟继承)?如何消除继承中的二义性?
  20. 使用H-lua框架制作魔兽争霸地图(1-准备阶段)

热门文章

  1. python数据结构与算法知识点_数据结构和算法基础知识点(示例代码)
  2. 拉丁正方形 java_Leetcode 221 最大正方形 动态规划
  3. python pytorch自定义_Pytorch 实现自定义参数层的例子
  4. 用python写聊天机器人_用Python 写一个机器人陪你聊天(文尾有彩蛋)
  5. Docker新手入门,最全详解看这里!
  6. wptx64能卸载吗_电脑可以卸载bonjour软件吗?详细介绍bonjour软件
  7. android开启前台服务_Android 知识点必知之ANR与OOM
  8. 手机浏览器网址_你真的会用浏览器搜索吗?几个高阶搜索技巧助您高效找到有用信息
  9. 人脸对齐(六)--ERT算法
  10. 汇编学习--6.13--基础知识