Educational Codeforces Round 122 (Rated for Div. 2)/codeforces1633
CodeForces1633
Div. 7
解析:
题目大意
给定 \(t\) 组数据。每组数据给定一个数 \(n\)(\(10\le n\le 999\))。
每次操作可以修改 \(n\) 任意一位上的数,将这一位上的数修改为 \(0\sim 9\) 之间的任意数。要求使用最少的修改次数使这个数修改后是 \(7\) 的倍数,并且没有多余的前导 \(0\)。输出修改后的数,如果有多组解,输出任意一种即可。如果已经是 \(7\) 的倍数,那么不需要修改。
思路:
发现修改个位一定能让 \(n\) 能被 \(7\) 整除,直接枚举个位换哪个数。
code
#include <bits/stdc++.h>
using namespace std;
signed main()
{
    int t; scanf ("%d", &t);
    while (t--)
    {
        int n; scanf ("%d", &n);
        if (n % 7 == 0) printf ("%d\n", n);
        else
        {
            n = n / 10 * 10;
            for (int i = n; i <= n + 10; i++)
                if (i % 7 == 0) { printf ("%d\n", i); break; }
        }
    }
    return 0;
}
Minority
解析:
题目大意:
- 给定一个 \(01\) 字符串 \(s\),定义 \(c_k(l,r)\) 表示 \(s\) 的由下标为 \([l,r]\) 中的字母构成的连续子串中 \(k\) 的个数。
 - 定义 \(f(l,r)=\begin{cases}c_0(l,r)&c_0(l,r)<c_1(l,r)\\c_1(l,r)&c_0(l,r)>c_1(l,r)\\0&c_0(l,r)=c_1(l,r)\end{cases}\),求 \(\max\limits_{1\le l\le r\le n}f(l,r)\)。多组询问。
 - \(T\le10^4,\sum|s|\le2\times10^5\)
 
思路:
诈骗题,\(f(1,n)\) 一定最大,因为这个区间含有的 \(0,1\) 都最多,如果 \(c_0(l,r)=c_1(l,r)\) 那个答案就是 \(c_0(l,r)-1\)(取 \([1,n-1]\))。
code:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
char ch[N];
int cnt1, cnt2;
signed main()
{
    int t; scanf ("%d", &t);
    while (t--)
    {
        cnt1 = cnt2 = 0;
        scanf ("%s", ch + 1);
        int n = strlen (ch + 1);
        if (n <= 2) { printf ("0\n"); continue; }
        for (int i = 1; i <= n; i++)
        {
            if (ch[i] == '0') cnt1++;
            else cnt2++;
        }
        if (cnt1 != cnt2) printf ("%d\n", min(cnt1, cnt2));
        else printf ("%d\n", cnt1 - 1);
    }
    return 0;
}
Kill the Monster
解析:
题目大意
在某款电脑游戏里,角色初始生命 \(hc\),初始攻击 \(dc\)。怪物初始生命 \(hm\),初始攻击 \(dm\)。
而你有 \(k\) 次机会,将攻击力永久提升 \(w\) 或者将生命永久提升 \(a\) 。
每一轮,角色攻击怪物,怪物掉 \(dc\) 生命。怪物攻击角色,角色掉 \(dm\) 生命。
问若干轮以后,角色能否击杀怪物并且角色存活。
击杀怪物定义为:怪物生命 \(\ngtr 0\)。
角色存活定义为:角色生命 \(>0\)。
思路:
枚举 \(0\to k\) 分别给攻击和生命多少次机会,如果某一时刻 $ \lceil\frac{hc}{dm}\rceil \ge \lceil\frac{hm}{dc}\rceil$ 那么就可以胜利。
code
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read ()
{
    int x = 0, f = 1;
    char ch = getchar ();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
    while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
    return x * f;
}
signed main()
{
    int t = read ();
    while (t--)
    {
        int hc = read (), dc = read ();
        int hm = read (), dm = read ();
        int k = read (), w = read (), a = read ();
        bool flag = false;
        for (int i = 0; i <= k; i++)
        {
            int h = hc + (i * a), d = dc + ((k - i) * w);
            if ((hm + d - 1) / d <= (h + dm - 1) / dm) { printf ("YES\n"); flag = true; break; }
        }
        if (!flag) printf ("NO\n");
    }
    return 0;
}
Make Them Equal
解析:
题目大意:
你有一个长度为 \(n\),初始全为 \(1\) 的数组 \(a\),和两个长度为 \(n\) 的数组 \(b,c\)。
你可以最多进行 \(k\) 次如下的操作:选择两个正整数 \(i,x\),使 \(a_{i}\) 变成 $ \left ( a_{i}+\left \lfloor \dfrac{a_{i}}{x} \right \rfloor \right )$。
最后,如果 \(a_{i}=b_{i}\),你将会获得 \(c_{i}\) 的收益。
最大化总收益。
- \(1 \leq t \leq 100,1 \leq n \leq 1000, 1 \leq k \leq 1 \times 10^{6}\)
 - \(1 \leq b_{i} \leq 1000,1 \leq c_{i} \leq 1 \times 10^{6}\);
 - \(\sum n \leq1000\)。
 
思路:
我们注意到 \(a_i\) 的初始值都是 \(1\),而 \(b_i\leq 1000\) 所以我们可以预处理出来每个值由 \(1\) 得到的最小次数,这部分预处理复杂度是 \(\mathcal O(V^2)\) 的。现在问题转化成了:
- 最多操作 \(k\) 次,还原第 \(i\) 个需要操作 \(cnt_{b_i}\) 次,可以得到 \(c_i\) 的价值,问最大价值。
 
发现问题变成了 01背包问题,复杂度 \(\mathcal O(nk)\),可能会被卡常,注意 \(k\geq \sum cnt_{b_i}\) 可以剪枝。
code:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000 + 10;
const int K = 1e6 + 10;
typedef pair <int, int> pii;
inline int read ()
{
    int x = 0, f = 1;
    char ch = getchar ();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
    while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
    return x * f;
}
int n, k;
int b[N], c[N], cnt[N * 2];
int dp[K];
void init ()
{
    memset (cnt, 0x3f, sizeof (cnt));
    cnt[1] = 0;
    for (int i = 1; i <= 1000; i++)
        for (int j = 1; j <= i; j++)
            cnt[i + i / j] = min (cnt[i + i / j], cnt[i] + 1);
}
signed main()
{
    int t = read ();
    init ();
    while (t--)
    {
        n = read (), k = read (); int sum = 0, s = 0;
        for (int i = 1; i <= n; i++) b[i] = read (), sum += cnt[b[i]];
        for (int i = 1; i <= n; i++) c[i] = read (), s += c[i];
        if (k >= sum) { printf ("%d\n", s); continue; }
        memset (dp, 0, sizeof (dp));
        for (int i = 1; i <= n; i++)
            for (int j = k; j >= cnt[b[i]]; j--)
                dp[j] = max (dp[j], dp[j - cnt[b[i]]] + c[i]);
        printf ("%d\n", dp[k]);
    }
    return 0;
}
Spanning Tree Queries
解析:
题目大意:
给定一个包含 \(n\) 个点和 \(m\) 条边的无向带权图,你有 \(k\) 次询问,第 \(i\) 次询问给定一个整数 \(q_i\),你需要从图中选出一棵生成树,设该生成树的 \(n-1\) 条边的权值为 \(w_1,w_2,\dots,w_{n-1}\),你需要求出 \(\sum\limits_{j=1}^{n-1}|w_j-q_i|\) 的最小值。
该题所有 \(k\) 次询问中,前 \(p\) 次询问的 \(q_1,q_2,\dots,q_p\) 在输入中给定,从第 \(p+1\) 次询问开始的 \(q_i=(q_{i-1}\cdot a+b)\bmod c\)。
- \(2\leqslant n\leqslant 50\),\(n-1\leqslant m\leqslant 300\),\(1\leqslant p\leqslant 10^5\),\(p\leqslant k\leqslant 10^7\),\(0\leqslant a,b\leqslant 10^8\),\(1\leqslant c\leqslant 10^8\)。
 - \(0\leqslant w_i\leqslant 10^8\)。
 
思路:
发现这道题的 \(k\leq 10^7\),也就是我们必须在 \(\log\) 的时间内处理每个答案,这样 \(\mathcal O(km\log m)\) 的 \(k\) 次 Kruskal 肯定不行,我们需要考虑预处理答案。
而绝对值有好的性质,我们按照边权排序后,正常 Kruskal 是从头到尾扫,而绝对值则要求先扫在数轴上更靠近 \(q_i\) 的边,我们可以二分找到 \(q_i\) 在边权 \(e_i\) 中的具体位置,并将边权分为两类:小于 \(q_i\) 和大于 \(q_i\) 的。
假设 \(e_1\le e_2\le\cdots\le e_j\le q_i\le e_{j+1} \le \cdots \le e_m\),
则必有 \(|e_1-q_i| \ge |e_2-q_i| \ge \cdots \ge |e_j-q_i|\) 且 \(|e_{j+1}-q_i| \le|e_{j+2}-q_i| \le \cdots \le |e_m-q_i|\),我们可以开两个队列分别从 \(j\to 1\),\(j+1\to m\) 维护每条边权,每次取两个队列中与 \(q_i\) 绝对值的较小值,这样就达到了排序的目的。
同时,我们注意到 \(m\leq 300\),也就是我们可以对每个 \(j\) 分别考虑,考虑每个 \(e_j\leq q\leq e_{j+1}\) 时的生成树情况,但对于即使对于同一个 \(j\),不同的 \(q\) 所对应的生成树也是可能不同的,即在两个队列中会造成不同的选数顺序,我们考虑这样的情况最多有 \(\begin{pmatrix} m \\ 2 \\ \end{pmatrix}\) 种不同的可能(在 \(m\) 条边中任选两条边取平均值),这样最终不同生成树的个数是 \(\mathcal O(m)\cdot\mathcal O(m^2)=\mathcal O(m^3)\) 种。
时间复杂度 \(\mathcal O(m^3\log m+k\log m^2)\)。
code:
#include <bits/stdc++.h>
#define int long long
#define eb emplace_back
#define lob lower_bound
using namespace std;
const int N = 300 + 10;
const int SN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
typedef pair <int, int> pii;
inline int read ()
{
    int x = 0, f = 1;
    char ch = getchar ();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar (); }
    while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar (); }
    return x * f;
}
int n, m;
int p, k, a, b, c;
struct edge {
    int u, v, w;
    bool operator < (const edge &A)const {
        return w < A.w;
    }
}e[N];
int g[SN], cnt;
int ans[SN], cntA[SN][2];
queue <int> que[2];
struct DSU {
    int fa[N];
    void init () { for (int i = 1; i <= n; i++) fa[i] = i; }
    inline int find (int x) { return x == fa[x] ? x : fa[x] = find (fa[x]); }
} d;
void clear (int k) { while (!que[k].empty ()) que[k].pop (); }
void kruskal (int id, int x)
{
    d.init ();
    clear (0); clear (1);
    int pos = lob (e + 1, e + m + 1, (edge) {0, 0, x}) - e;
    for (int i = pos - 1; i >= 1; i--) que[0].push (i);
    for (int i = pos; i <= m; i++) que[1].push (i);
    while (!que[0].empty () || !que[1].empty ())
    {
        int c, cid;
        if (que[0].empty ()) c = 1, cid = que[1].front ();
        else if (que[1].empty ()) c = 0, cid = que[0].front ();
        else
        {
            if (abs (x - e[que[0].front ()].w) <= abs (x - e[que[1].front ()].w)) c = 0, cid = que[0].front ();
            else c = 1, cid = que[1].front ();
        }
        int fx = d.find (e[cid].u), fy = d.find (e[cid].v);
        if (fx != fy)
        {
            d.fa[fx] = fy;
            ans[id] += abs (x - e[cid].w);
            cntA[id][c]++;
        }
        que[c].pop ();
    }
}
int Xor;
inline int getans (int q)
{
    int x = lob (g + 1, g + cnt + 1, q) - g;
    return ans[x] - cntA[x][0] * (g[x] - q) + cntA[x][1] * (g[x] - q);
}
signed main()
{
    n = read (), m = read ();
    for (int i = 1; i <= m; i++)
        e[i].u = read (), e[i].v = read (), e[i].w = read ();
    sort (e + 1, e + m + 1);
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= m; j++)
            g[++cnt] = (e[i].w + e[j].w) >> 1;
    g[++cnt] = INF;
    sort (g + 1, g + cnt + 1);
    cnt = unique (g + 1, g + cnt + 1) - g - 1;
    for (int i = 1; i <= cnt; i++) kruskal (i, g[i]);
    p = read (), k = read (), a = read (), b = read (), c = read ();
    int q;
    for (int i = 1; i <= p; i++) { q = read (); Xor ^= getans(q); }
    for (int i = p + 1; i <= k; i++) { q = (q * a + b) % c; Xor ^= getans(q); }
    printf ("%lld\n", Xor);
    return 0;
}
6
解析:
题目大意:
思路:
没读题,先咕了
code:
												
											Educational Codeforces Round 122 (Rated for Div. 2)/codeforces1633的更多相关文章
- Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship
		
Problem Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...
 - Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)
		
Problem Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...
 - Educational Codeforces Round 43 (Rated for Div. 2)
		
Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...
 - Educational Codeforces Round 35 (Rated for Div. 2)
		
Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...
 - Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
		
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...
 - Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
		
Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...
 - Educational Codeforces Round 63 (Rated for Div. 2) 题解
		
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
 - Educational Codeforces Round 39 (Rated for Div. 2) G
		
Educational Codeforces Round 39 (Rated for Div. 2) G 题意: 给一个序列\(a_i(1 <= a_i <= 10^{9}),2 < ...
 - Educational Codeforces Round 48 (Rated for Div. 2) CD题解
		
Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...
 
随机推荐
- Redis 04 列表
			
参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 在 Redis ...
 - Python逆向爬虫之pyquery,非常详细
			
系列目录 Python逆向爬虫之pyquery pyquery是一个类似jquery的python库,它实现能够在xml文档中进行jQuery查询,pyquery使用lxml解析器进行快速在xml和h ...
 - 硬件错误导致的crash
			
[683650.031028] BUG: unable to handle kernel paging request at 000000000001b790--------------------- ...
 - 美丽的神话 flac 成龙/金喜善  美丽的神话 mp3 韩红/孙楠
			
这里分享从网上收集的俩个版本的歌,都很不错,有兴趣的可以听听 以下是成龙/金喜善 flac 版本,音质不错: 美丽的神话成龙/金喜善解开我最神秘的等待星星坠落风在吹动终于再将你融入怀中两颗心颤抖相信我 ...
 - .Net Core 配置文件读取 - IOptions、IOptionsMonitor、IOptionsSnapshot
			
原文链接:https://www.cnblogs.com/ysmc/p/16637781.html 众所周知,appsetting.json 配置文件是.Net 的重大革新之心,抛开了以前繁杂的xml ...
 - 《Java编程思想》读书笔记(三)
			
前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十一章到第十六章的内容,这一次 ...
 - KingbaseES DENSE_RANK 函数用法
			
DENSE_RANK()函数用于为结果集分区内的每一行分配一个排名,排名值之间没有差距,函数为结果集的每个分区中的每一行分配一个等级. 与 RANK() 函数不同的是,DENSE_RANK() 函数总 ...
 - 来点基础的练习题吧,看见CSDN这类基础的代码不多
			
来点基础的练习题吧,看见CSDN这类基础的代码不多 //正三角形 void ex03(){ int i,k=0, rows, space; printf("请输入三角形的层次:") ...
 - 快速排序C语言版图文详解
			
 算法原理:选一个数位基准,将序列分成两个部分,一边全是比它小序列,另一边全是比它大序列.然后再分别对比他小的序列和比再次进行基准分割.依次分割下去,得到一个有序的队列. 原理图示: 编辑 编辑 ...
 - ELK Stack 日志平台性能优化
			
转载自: https://mp.weixin.qq.com/s?__biz=MzAwNTM5Njk3Mw==&mid=2247487789&idx=1&sn=def0d8c2e ...