Educational Codeforces Round 102 (Rated for Div
Educational Codeforces Round 102 (Rated for Div. 2)
No More Inversions
给定\(k\),序列\(a\)长度为\(n\):\(1,2,3...k,k-1,k-2...k-(n-k)\),设序列\(a\)中逆序数为\(m\),给定排列\(p:1,2,3...k\),利用该排列形成新的序列\(b:b[i]= p[a[i]]\), 请你构造排列\(p\)使得序列\(b\)的逆序数不超过\(m\),且序列\(b\)字典序最大
题解:构造 + 思维 + 回文串的逆序对 : 记一下结论
引理:长度相同且元素不重复的回文串(\([s_1,s_2...s_k...s_2,s_1]\))逆序对恒定相等,其逆序数为\((k-1)^2\)
证明:
任选\(s_i,i<=k-1\),那么\(s_i...s_k...s_i\)三个之间一定会形成一个逆序对,那么这样的组合一共有\(k-1\)个,所以一定会产生\(k-1\)个逆序对
任选\(s_i,s_j且i,j<=k-1\),那么\(s_i...s_j...s_j...s_i\)四个之间一定会形成两个逆序对,那么这样的组合一共有\(C_{k-1}^{2}\)个,所以一定会产生\(2*C_{k-1}^{2}\)个逆序对
那么最终合并两种情况产生的逆序对,总共产生\((k-1)^2\)个逆序对
我们发现对于任意排列\(p\),假设\(p:[1,2,3,4]\),\(n=6\),那么序列\(b\)一定是\([1,2,3,4,3,2]\),也就是说\([k-(n-k),n]\)之间一定形成回文串,我们发现对于序列\(a\)而言,恰好也是在\([k-(n-k),n]\)之间形成回文串,根据引理得知两者之间逆序数相同,因为序列\(b\)的逆序数不能超过序列\(a\),所以对于序列\(b\)而言\([1,k-(n-k)-1]\)一定不能产生逆序对,也就是说前面一定为\(1,2,3...k-(n-k)-1\),那么如果想要使得字典序最大我们只要使得排列\(p\)在\([k-(n-k),k]\)中翻转即可,例如上述样例\(p:[1,4,3,2],b:[1,4,3,2,3,4]\)
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, k;
void solve()
{
cin >> n >> k;
for (int i = 1; i <= (k - (n - k) - 1); ++i)
cout << i << " ";
for (int i = k; i >= (k - (n - k)); --i)
cout << i << " ";
cout << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
Program
一共有\(n\)次操作,\(x\)初始值为\(0\),每次操作可以使\(x\)加1或减1,现在给出\(m\)次询问,每次询问给出\(l,r\),要求不执行\([l,r]\)之间的操作,让你给出如果只执行其他操作的话一共\(x\)会出现多少个不同的值
题解:前缀/后缀维护最值
我们思考如何得出答案:我们只要知道这些操作之中\(x\)的最大值和最小值就能知道出现多少个不同的值
我们只需要将每次操作看成-1或1,得到前缀和\(pre\),然后维护\(pre\)的前缀以及后缀最大值、最小值
对于询问\([l,r]\)来说,首先\([1,l-1]\)之间的最大值和最小值不会受到影响,但是\([r+1,n]\)之间的最大值和最小值会受到影响,实际上模拟后发现只需要在后缀最大值和最小值中减去\(pre[r]-pre[l-1]\)就能消除影响
本题也可以通过线段树维护区间最值求解,消除影响也是通过减去\(pre[r]-pre[l-1]\)
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, q;
int pre[N];
int pre_min[N], pre_max[N];
int suf_min[N], suf_max[N];
void solve()
{
cin >> n >> q;
string s;
cin >> s;
s = " " + s;
for (int i = 1; i <= n; ++i)
{
if (s[i] == '-')
pre[i] = pre[i - 1] - 1;
else
pre[i] = pre[i - 1] + 1;
pre_min[i] = min(pre_min[i - 1], pre[i]);
pre_max[i] = max(pre_max[i - 1], pre[i]);
}
suf_max[n + 1] = suf_min[n + 1] = pre[n];
for (int i = n; i >= 1; i--)
{
suf_min[i] = min(suf_min[i + 1], pre[i]);
suf_max[i] = max(suf_max[i + 1], pre[i]);
}
while (q--)
{
int l, r;
cin >> l >> r;
int sum = pre[r] - pre[l - 1];
int maxx = max(pre_max[l - 1], suf_max[r + 1] - sum);
int minn = min(pre_min[l - 1], suf_min[r + 1] - sum);
cout << maxx - minn + 1 << endl;
}
}
signed main(void)
{
Zeoy;
int T = 1;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
Minimum Path
现给定有权无向图,\(n\)个点,\(m\)条边,定义两点之间路径的权值为:路径上所有边的权值之和\(-\)路径上的最大边权\(+\)路径上的最小边权;先让你求出原点\(1\)到其他每个节点路径的最小权值
题解:分层图最短路
因为要求的是路径最小权值,我们贪心的想删去最大权值边和加上最小权值边,我们将题目转化为删去任意一条边然后一条边加上两次,那么我们实现加减操作可以建立分层图:
- 建立四层图(将每个点拆成4个),每层正常建边
- 连接第一层到第二层的边权为\(0\),代表删去一条边
- 连接第二层到第四层(答案层)的边权为\(2*w\),代表一条边加上两次
- 但是第三层有什么用呢?实际上我们前面分层情况代表了先出现最大边后出现最小边,但是另一种情况就是先出现最小边再出现最大边,所以我们连接第一层到第三层的边权为\(2*w\),连接第三层到第四层(答案层)的边权为\(0\)
- 最后答案就在第四层,但是需要注意有些点和\(1\)直接相连,那么它既作为最大值也作为最小值,最后路径权值就等于路径上边权之和,所以我们需要特判一下\(min(dis[i],dis[i+3*n])\)
建完图后跑一遍\(dij\)即可
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10;
int n, m;
vector<pii> g[N << 2];
int dis[N << 2];
int vis[N << 2];
void dij(int st)
{
for (int i = 1; i <= 4 * n; ++i)
dis[i] = INF;
dis[st] = 0;
priority_queue<pii, vector<pii>, greater<pii>> q;
q.push({dis[st], st});
while (q.size())
{
int u = q.top().second;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
for (auto [v, w] : g[u])
{
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push({dis[v], v});
}
}
}
}
void solve()
{
cin >> n >> m;
for (int i = 1, u, v, w; i <= m; ++i)
{
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
g[u + n].push_back({v + n, w});
g[v + n].push_back({u + n, w});
g[u + 2 * n].push_back({v + 2 * n, w});
g[v + 2 * n].push_back({u + 2 * n, w});
g[u + 3 * n].push_back({v + 3 * n, w});
g[v + 3 * n].push_back({u + 3 * n, w});
g[u].push_back({v + n, 0});
g[v].push_back({u + n, 0});
g[u].push_back({v + 2 * n, 2 * w});
g[v].push_back({u + 2 * n, 2 * w});
g[u + n].push_back({v + 3 * n, 2 * w});
g[v + n].push_back({u + 3 * n, 2 * w});
g[u + 2 * n].push_back({v + 3 * n, 0});
g[v + 2 * n].push_back({u + 3 * n, 0});
}
dij(1);
for (int i = 2; i <= n; ++i)
cout << min(dis[i], dis[i + 3 * n]) << " ";
cout << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
Educational Codeforces Round 102 (Rated for Div的更多相关文章
- Educational Codeforces Round 102 (Rated for Div. 2)
比赛地址 A(水题) 题目链接 题目: 给出一个数组\(a\)并能进行一个操作使得数组元素更改为数组任意其他两元素之和,问是否可以让数组元素全部小于等于\(d\) 解析: 排序后判断最大值是否小于等于 ...
- Educational Codeforces Round 102 (Rated for Div. 2) D. Program (思维,前缀和)
题意:给你一个只含\(+\)和\(-\)的字符串,给你一个数\(x\),\(x\)初始为\(0\),随着字符串的遍历会加一减一,现在有\(m\)个询问,每个询问给出一个区间\([l,r]\)表示将这个 ...
- Educational Codeforces Round 102 (Rated for Div. 2) B. String LCM (构造,思维)
题意:给你两个字符串\(a\)和\(b\),找出它们的\(lcm\),即构造一个新的字符串\(c\),使得\(c\)可以由\(x\)个\(a\)得到,并且可以由\(y\)个\(b\)得到,输出\(c\ ...
- 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 给出一个字符串,现在可以对这个字符串进 ...
随机推荐
- Redis 入门 - 安装最全讲解(Windows、Linux、Docker)
经过上一章节的介绍,相信大家对Redis已经有了大致的认知,今天主要给大家详细讲解Redis在Windows.Linux.Docker下的安装过程. 01.Windows 下面给大家介绍三种在Wind ...
- VMware安装CentOS7及远程登录详细教程
写在前面 主要使用软件: VMware Workstation Pro17 Navicat Premium17 Xshell7 Xftp7 1.在虚拟机安装CentOS7 访问阿里云镜像站 ,选择标记 ...
- JavaScript Library – Lit
前言 我写过一篇关于 Lit 的文章,Material Design, Angular Material, MDC, MWC, Lit 的关系. 如今 material-web MWC 已经发布 1. ...
- DOM – Dimension & Coordinate (offset, client, computed, rect)
前言 很多年前有记入过一篇 box-sizing 和 dom width. 想想也挺可悲的, 那年我是负责后端的, 却要帮着前端去学习这些知识来解决问题... 也好, 现在 full stack, 也 ...
- js 翻译 c# 注意事项
1. split('') 在 c# 是不可以 .Split("") 的 要写 ToCharArray() 更新: 2021-09-25, split('') 是不好的写法, es6 ...
- 【渗透测试】ATT&CK靶场一,phpmyadmin,域渗透,内网横向移动攻略
前言 VulnStack,作为红日安全团队匠心打造的知识平台,其独特优势在于全面模拟了国内企业的实际业务场景,涵盖了CMS.漏洞管理及域管理等核心要素.这一设计理念源于红日安全团队对ATT&C ...
- c++可变模板参数
在C++中的可变模板参数使用省略号 ... 来表示一个参数包(Parameter Pack),其具体位置决定了这个包是模板参数包还是函数参数包,以及如何进行参数展开. 1. 模板参数包:c... Ar ...
- Blazor 子组件与父组件通过 ChildEvents 传递数据的方法
想要实现 Blazor 子组件向父组件传递数据, 参考 痴者工良的博文所描述的方式, .Net 5.0 下编译未能通过, 于是先修改一下, 简化为光触发事件通知而不传值 子组件 Child.razor ...
- arm64 下内核 crash—— 非法地址
下面是在实际工作中遇到的一次内核(5.4.110)访问非法内存地址(空指针)导致出错的现场,在这里记录一下简单的分析流程为以后遇到类似的问题作为参考. [ 220.619861] Unable to ...
- 80篇国产数据库实操文档汇总(含TiDB、达梦、openGauss等)
国产数据库发展得如火如荼,数据库的国产化替代也正在进行中.最近,有越来越多的朋友都加入了学习国产数据库的队伍中,本文便选取了墨天轮技术社区的国产数据库流行度排行榜上排名靠前的几个数据库,整理了相关的实 ...