链接:Codeforces Round #636 (Div. 3)
A - Candies
题意:求出一个x满足x+2∗x+4∗x+⋯+2k−1∗x=n且k>1
思路:提出x得x∗(1+2+4+⋯+2k−1)=n,从小到大枚举k,直到满足n∣(1+2+4+⋯+2k−1)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>using namespace std;int T, n;int main()
{// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &T);while (T--) {scanf("%d", &n);int now = 3, t = 4;while (0 != n % now) {now += t;t *= 2;}printf("%d\n", n / now);}return 0;
}

B - Balanced Array
题意:给你一个偶数n,要求你构造出一个数列,满足前n2个数为偶数,后n2个数为奇数,每个数都为互不相同的正整数,且前n2个数的和等于后n2个数的和
思路:奇数和偶数的差为奇数,如果n2−1为奇数,那么对于前n2−1对奇数和偶数,合起来的差为偶数,那么第n2对奇数和偶数就无法构造出来,所以n2必须为偶数,即n∣4,显然可以构造出这样的数列2 4 6⋯n 1 3 5⋯(n−3) (n+n2−1)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>using namespace std;int T, n;int main()
{// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &T);while (T--) {scanf("%d", &n);if (n % 4) {printf("NO\n");continue;}printf("YES\n");for (int i = 1; i <= n / 2; i++) printf("%d ", 2 * i);for (int i = 1; i <= n / 2 - 1; i++) printf("%d ", 2 * i - 1);printf("%d\n", n + n / 2 - 1);}return 0;
}

C - Alternating Subsequence
题意:就是给你n个数,你需要找出其中的最长子序列,并且这个子序列是正负交替的,并且尽量让这个子序列的和最大
思路:由于要子序列最长,所以把n个数按照正负分成几块(块内元素正负性相同),然后再在每个块内贪心取一个数即可

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>using namespace std;typedef long long ll;const int N = 200010;
const ll INF = 1000000000000000000;int T, n;
ll a[N];void solve(ll &imax, ll &imin, int l, int r)
{for (int i = l; i <= r; i++) {imax = max(imax, a[i]);imin = max(imin, a[i]);}
}int main()
{// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &T);while (T--) {scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);int lst = 1, now = 2;ll res = 0;while (now <= n) {if ((a[now] > 0) != (a[now - 1] > 0)) {ll imax = -INF, imin = -INF;solve(imax, imin, lst, now - 1);if (a[lst] > 0) res += imax;else res += imin;lst = now;}now += 1;}ll imax = -INF, imin = -INF;solve(imax, imin, lst, n);if (a[lst] > 0) res += imax;else res += imin;printf("%lld\n", res);}return 0;
}

D - Constant Palindrome Sum
题意:给定一个长度为n的数列,n为偶数,保证每个元素在[1,k]之间,每次操作可以把某个位置的数字变成[1,k]内的任意数字,要求让这个数列满足:对于所有的i∈[1,n2],a[i]+a[n-i+1]是一个定值,问最少的操作次数
思路:设imin=min(a[i],a[n-i+1]),imax=max(a[i],a[n-i+1]),分三种情况,不进行操作a[i]+a[n-i+1]不变,操作一次能够使a[i]+a[n-i+1]∈[imin+1,imax+k],操作两次能使a[i]+a[n-i+1]∈[2,2k],根据贪心的思想,对于每一对(a[i],a[n-i+1]),[imin+1,imax+k]操作次数加1,[2,imin]和[imax+k+1,2k]操作次数加2,a[i]+a[n-i+1]操作次数不变,用差分数组维护一下,最后找到[2,2*k]内的最小操作次数即可

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>using namespace std;const int N = 400010;
const int INF = 0x3f3f3f3f;int T, n, k, a[N], b[N];void add(int *d, int l, int r, int x)
{d[l] += x;d[r + 1] -= x;
}int main()
{// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &T);while (T--) {scanf("%d%d", &n, &k);for (int i = 1; i <= 2 * k; i++) b[i] = 0;for (int i = 1; i <= n; i++) scanf("%d", &a[i]);for (int i = 1; i <= n / 2; i++) {int imin = min(a[i], a[n - i + 1]);int imax = max(a[i], a[n - i + 1]);if (2 <= imin) add(b, 2, imin, 2);add(b, imin + 1, imax + k, 1);if (imax + 1 <= k) add(b, imax + k + 1, 2 * k, 2);}for (int i = 1; i <= 2 * k; i++) b[i] += b[i - 1];for (int i = 1; i <= n / 2; i++) b[a[i] + a[n - i + 1]] -= 1;int res = INF;for (int i = 2; i <= 2 * k; i++) res = min(res, b[i]);printf("%d\n", res);}return 0;
}

E - Weights Distributing
题意:给定一张n个顶点的有权无向图,m条边和m个权值和三个点a,b,c。问如何分配边权能使a到b,b再到c的权值和最小,求最小值
思路:很直观的感受就是,求出a到b,b再到c的最短路径,然后将m个权值从小到大分配即可,如果同时有多条最短路径,我们应该选择重合最多的两条最短路径(因为这样用的边会更少),并且此时重合的部分应该分配权值最小的边,所以我们可以用bfs或者dfs求出a,b,c到其他所有点的最短距离da[],db[],dc[],然后枚举每个点x,假设a到b,b再到c的路径拆为a到x,x到b,b到x,x再到c,枚举所有的点x,一定会包含上述的两种(两条路径重叠与不重叠)的情况,并且此时b到x应该分配最小的边权,将m个边权排序,求前缀和sum[],那么对于点x,答案就是sum[db[x]]+sum[da[x]+db[x]+dc[x]]
参考

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>using namespace std;typedef long long ll;const int N = 200010;
const int INF = 0x3f3f3f3f;struct node {int to, nex;
};int T, n, m, a, b, c;
ll p[N], sum[N];
int head[N], cnt, da[N], db[N], dc[N];
node edge[2 * N];
queue<int> q;void init()
{cnt = 0;for (int i = 1; i <= n; i++) head[i] = 0;for (int i = 1; i <= n; i++) da[i] = db[i] = dc[i] = INF;
}void add_edge(int u, int v)
{edge[++cnt].to = v;edge[cnt].nex = head[u];head[u] = cnt;
}void bfs(int s, int *d)
{while (!q.empty()) q.pop();d[s] = 0;q.push(s);while (!q.empty()) {int u = q.front();q.pop();for (int i = head[u]; 0 != i; i = edge[i].nex) {int v = edge[i].to;if (d[v] != INF) continue;d[v] = d[u] + 1;q.push(v);}}
}int main()
{// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &T);while (T--) {scanf("%d%d%d%d%d", &n, &m, &a, &b, &c);init();for (int i = 1; i <= m; i++) scanf("%lld", &p[i]);sort(p + 1, p + m + 1);for (int i = 1; i <= m; i++) sum[i] = sum[i - 1] + p[i];for (int i = 1; i <= m; i++) {int u, v;scanf("%d%d", &u, &v);add_edge(u, v);add_edge(v, u);}bfs(a, da);bfs(b, db);bfs(c, dc);ll res = 1000000000000000000;for (int i = 1; i <= n; i++) {if (da[i] + db[i] + dc[i] > m) continue;res = min(res, sum[db[i]] + sum[da[i] + db[i] + dc[i]]);}printf("%lld\n", res);}return 0;
}

编写人:刘枝飞

Codeforces Round #636 (Div. 3)部分题解相关推荐

  1. Codeforces Round #636 (Div. 3) F. Restore the Permutation by Sorted Segments 思维 + 暴力

    传送门 文章目录 题意: 思路: 题意: n≤200n\le200n≤200 思路: 首先关注到rrr从[2,n][2,n][2,n]都出现一次,所以很明显最后一个位置只出现一次,但是这样倒着来不是很 ...

  2. Codeforces Round #636 (Div. 3) E. Weights Distributing 思维 + bfs

    传送门 文章目录 题意: 思路: 题意: n≤2e5,m≤2e5n\le2e5,m\le2e5n≤2e5,m≤2e5 思路: 怎么感觉每场div3div3div3都有一个巧妙的图论题. 首先如果只有两 ...

  3. Codeforces Round #636 (Div. 3) D. Constant Palindrome Sum 思维 + 差分

    传送门 文章目录 题意: 思路: 题意: 思路: 首先有一个显然的性质就是每组操作最多不会超过两次. 很容易想到一个很暴力的思路,就是枚举x∈[1,2∗k]x \in [1,2*k]x∈[1,2∗k] ...

  4. Codeforces Round #686 (Div. 3) A-F题解

    Codeforces Round #686 (Div. 3) A-F题解 A. Special Permutation 题意 给定 nnn ,输出一个长度为 nnn 的全排列,每个位置 iii 上的数 ...

  5. Codeforces Round #693 (Div. 3)部分题解

    Codeforces Round #693 (Div. 3) 部分题解 D. Even-Odd Game 思路: 贪心:田忌赛马 (1)先将数组从大到小排序,取数时从大到小取,用一个ans变量记录取数 ...

  6. Codeforces Round #702 (Div. 3)A-G题解

    Codeforces Round #702 (Div. 3)A-G题解 比赛链接:https://codeforces.ml/contest/1490 这场F读错题意白给一发,G二分的if(dp[mi ...

  7. codeforces Round #645 (Div. 2)D题解

    Codeforces Round #645 (Div. 2)--D题解 作为一名菜鸡,理所当然得没有A出来,这道题数据放小就一水题了,可惜数据这块卡的死死的. 本题最重要的一点就是你要推出来一个结论: ...

  8. Codeforces Round #670 (Div. 2)A-D题解

    Codeforces Round #670 (Div. 2)A-D题解 //写于rating值1987/2184 //补档 比赛链接:https://codeforces.ml/contest/140 ...

  9. Codeforces Round #674 (Div. 3)A-F题解

    Codeforces Round #674 (Div. 3)A-F题解 比赛链接:https://codeforces.com/contest/1426 A题 水题不写题解 #include<b ...

最新文章

  1. JAVA中定义常量的几种方式
  2. ajax分页实现(php)
  3. 一个改变世界的“箱子”
  4. 关闭NPC call(__)
  5. 广度优先搜索(入门)
  6. (WebKit) ViewPort + Backing Store + Page Content
  7. P4070 [SDOI2016]生成魔咒
  8. 如何估算代码量_千万级用户的大型网站,应该如何设计其高并发架构?(彩蛋)...
  9. ExtJS 4.2 教程-07:Ext.Direct
  10. php对象复制,PHP 对象复制 - 对象复制 - phpStudy
  11. [2018.10.25 T3] 旅程
  12. 搜狗关键词挖掘工具,搜狗权重关键词挖掘工具
  13. 地震matlab频域分析,基于matlab的地震数据的分析.doc
  14. mac打开软件显示没有权限不能打开
  15. ASP利用IP138获IP地理位置
  16. 计算机相关商标,计算机的商标是属于哪一类?
  17. 同济高等数学第三章之经典错误知识点笔记
  18. chatgpt简单的问答机器人
  19. 向量、矩阵、实数、复数之间的各种运算方法
  20. ubuntu20.04 双显卡安装

热门文章

  1. 俞敏洪:坚持下去不是因为我很坚强,而是因为我别无选择
  2. sublime text 浏览器快捷键访问设置及常用快捷键整理
  3. 合理分析竞争对手,有效提升关键词排名
  4. C++移动拷贝构造函数
  5. xml文件解析 (DOM4J解析XML) -java
  6. PHP:2019年你面试会遇到的题目及解答(汇总)
  7. 网页显示的几种常用字体
  8. 华为鸿蒙系统与苹果IOS系统,华为鸿蒙与苹果iOS的两极之路
  9. 后端validated校验
  10. SEOer淘宝电商网站店铺优化使用的神奇工具